Remove orig files.

ubuntu/cosmic
Simon Quigley 6 years ago
parent 13c3cb2a1c
commit 82183449ff

7
.gitignore vendored

@ -1,7 +0,0 @@
/*.debhelper
/*.log
/*.substvars
/debhelper-build-stamp
/files
/qterminal/

@ -1,28 +0,0 @@
Project maintainer: Petr Vanek <petr@scribus.info>
Contributors:
Alexander Sokolov <sokoloff.a@gmail.com>
Alf Gaida <agaida@siduction.org>
Christian Surlykke <christian@surlykke.dk>
Daniel O'Neill <doneill@cammy.riverroadcable.com>
Erik Ridderby <erik@ridderby.se>
Felix Schnizlein <felix@fix3d.net>
Francisco Ballina <zballinita@gmail.com>
Ilya87 <yast4ik@gmail.com>
Jerome Leclanche <jerome@leclan.ch>
Johannes Jordan <ypnos@lanrules.de>
Ludger Krämer <dbluelle@blau-weissoedingen.de>
Maxim Bourmitrov <maxim.bourmistrov@unixconn.com>
Mikhail Ivchenko <ematirov@gmail.com>
Sweet Tea Dorminy <sweettea@mit.edu>
Vladimir Kuznetsov <vovanec@gmail.com>
Matteo Pasotti <matteo@mageia.it>
@kulti <kultihell@gmail.com>
Translators:
@pisculichi <pisculichi@openmailbox.org>
Sérgio Marques <smarquespt@gmail.com>
Valter Nazianzeno <manipuladordedados@gmail.com>

@ -1,358 +0,0 @@
qterminal-0.9.0 / 2018-05-21
============================
* Bump version to 0.9.0
* Spanish translation update
* Now building out-of-source is mandatory
* Fix tab texts, especially for vertical tabs
* CMake: Prevent in-source builds
* Fixed some lxde mentions
* Sort color schemes alphabetically
* Support modifying $TERM and use xterm-256color by default
* Convert connect to the new syntax - termwidgetholder.cpp
* Convert connect to the new syntax - termwidget.cpp
* Convert connect to the new syntax - tabwidget.cpp
* Convert connect to the new syntax - propertiesdialog.cpp
* Convert connect to the new syntax - mainwindow.cpp, part 1
* Convert connect to the new syntax - fontdialog.cpp
* Convert connect to the new syntax - bookmarkswidget.cpp
* Fix tabbar
* Close tab on middle clicking
* A real shortcut editor
* Allow to change tab title color
* Make tab closing button configurable
* Make active tab text bold to make it more visible
* Fix a typo
* Fixes an error in the d3fa804 fix of #304
* new config: show terminal size on resize
* Fixes #304
* Fix bracket paste
* Fixes tabAt() when tabBar is not at north position
* Fix terminal menubar
* Drop Qt foreach
* Set QTERMWIDGET_MINIMUM_VERSION
* Fix a typo in qterminal_drop.desktop
* Fix tab icon display in proxy style.
* Switch tab eliding to ElideMiddle.
* Adjust default tab width to 500 and enable limit by default.
* Forward declare TabBar.
* Add option for configuring tab width limit.
* Add maximum tab width and proper text eliding.
* Enable bidi by default
* Fix UI
* Add RTL support button
* Update Catalan translation
0.8.0 / 2017-10-21
==================
* Release 0.8.0: Update changelog
* Set version to 0.8.0
* Update information on distribution package
* Added legacy font setting support
* Made font in settings file human readable
* Fix action inconsistency when switching tabs
* Lithuanian translation
* Added Lithuanian language
* Don't export github templates
* correct spelling mistake
* Adapt to QTermWidget API changes after DECSCUSR handling
* liblxqt dont make sense here
* Copied issue template
* Drops Qt5Core_VERSION_STRING
* Update qterminal_drop.desktop
* Update qterminal.desktop
* Make disabled actions consistent at all times (#331)
* DBus DropMode (#325)
* Change subterminal shortcuts to avoid breaking qtermwidget scrolling (#327)
* Update main.cpp (#322)
* Fix toggle menu action.
* Focus highlight (#266)
* Replace numbered terminals with directional navigation (#255)
* Fix '1 Terminal' preset (#324)
* Change "Clear Current Tab" into "Clear Active Terminal" (#268)
* Fix duplicated items, rework MainWindow memory-management (#313)
* Fixed comment - needless compiler warnings are annoying (#321)
* DBus integration (#307)
* Restore filter actions (#310)
* New features: trim \n from pasted strings, confirm multiline pastes (#309)
* Support custom QSS styles
* Call QApp destructor (#306)
* Fixes (#318)
* Refactor dangling actions, delete windows on close
* Adds superbuild support
* Improve translation (.ts) handling
* Removes Qt5X11Extras_DEFINITIONS
* Stops adding not exist entries to CMAKE_MODULE_PATH
* Use the LXQtCompilerSettings module
* Adapt to QTermWidget improved CMake
* Fix a copy/paste error from 4afcc4d0d0922f526f89aadf16ec0517f6b5267e
* Update dependencies and cleanup trailing spaces
0.7.1 / 2016-12-21
==================
* Release 0.7.1: Update changelog
* Bump patch version (#294)
* Add common shortcuts for switching tabs (#275)
* Fix tabstop order in properties dialog & add buddy relations for labels. (#290)
* Add preferences for background images (#273)
* Disable menu actions that are not applicable currently (#244)
* DEFINES += STR_VERSION=\\\"0.7.0\\\"
* Add context menu actions for URLs and E-Mail addresses (#276)
* Removed minimum size (#265)
* Set maxval of dropdown spinboxen to 100, instead of 99
* Use the new lxqt-build-tools package
* Fix context menu actions being applied to the window opened last (#235)
* Show exit confirmation dialog when closing the last window tab (#242)
* remove "building with cpack" from CMakeLists.txt - not used anymore Added very basic .gitattributes
0.7.0 / 2016-09-24
==================
* Release 0.7.0: Add changelog
* Bump version to 0.7.0 (#262)
* Update README.md
* Collapse splitter hierarchies containing a single terminal (#254)
* Make qterminal.appdata.xml valid (#257)
* Add config option for changing window's title/icon
* Add support for automatic title & icon modification
* Delete Properties instance on exit (#239)
* Fix compilation warning related to QXmlStreamReader (#247)
* Set the desktopFileName property
* Fix typo in the conditional expression
* Add location for custom color schemes (#234)
* CMake Support changes (#237)
* Add keyboard cursor shape setting (#228)
* made the .pro file work on openSUSE; #229 (#232)
* Fix renaming a tab from the menu
* Make the rename current session shortcut work and configurable
* build: Use external translations
* ts-files removal (#222)
* Add pt_BR (Brazilian Portuguese) translation (#215)
* Merge pull request #214 from f2404/212_collapse_segfault_fix
* Remove noisy qDebug()
* Fix jumbled prompt
* Add Greek (el) translation
* Missing equal symbol for xml template
* Delete MainWindow on exit
* Link to the current github projects and trackers
* Apply context menu to the tab that it was opened over
* Close tabs in reverse order
* Eliminate memory leaks by closing tabs on exit
* Russian translation update
* Fix menubar transparency
* Fix default settings width
* Fix bookmarks widget transparency
* Use the same icon for dropdown and regular terminal
* Fix license file
* Improve README and use markdown
* Fixed button focus in close confirmation (resolves #179).
* Updated german translation.
* Fix Simplified Chinese(zh_CN)
* Update japanese translation
* Add Japanese translation to *.desktop
* fixed #174 XDG_CONFIG_DIRS support - read system wide QSettings
* Fix license issues within qterminal
* Add chinese translation
* Require Qt 5.2 or higher
* fix private header dependency for X11 global shortcuts
* fix searching for Qt5 private headers
* make only terminal widget transparent, not the parent window
* Fix japanese translation
* Russian translation update
* Add Japanese translation
* fixed #160 FTBFS as of commit 4967123
* Fixes for Portuguese language
* Fixes missing App Window icon
* Hungarian translation added
* Update qterminal_tr.ts
* Create qterminal_tr.ts
* do not overwrite settings in migrateSettings
* remove fullscreen patch
* migrateSettings add size and pos and rm geometry
* split geometry into size and position
* define saveGeomOnExit in properties.h
* add save geometry on exit
* Add Alt-<letter> shortcuts to all menu items.
* Make sure no settings are overwritten in migrateSettings().
* Update index property of tabs when tabs are moved by drag-and-drop.
* Update german translation.
* Corrected terminology in settings (transparency vs. opacity). Now transparency instead of opacity is used in the whole application consistently.
* Migrate AlwaysShowTabs-setting.
* Move migrateSettings()-method to Properties-class and call it *before* loadSettings().
* Update version number in settings.
* Renamed always show tabs setting.
* Portuguese update
* Add instructions to disable system qxt when building with Qt5.
* Changed position of font button in settings.
* Changed layout of font-setting to better fit to the other settings in the widget.
* Appdata file for QTerminal (resolves #60).
* Add view-menu actions to mainwindow, to make them available when menu bar is hidden.
* Add fullscreen mode.
* Ignore user-specific project files of QtCreator.
* Resolves #115: Store Actions of 'View'-menu in properties too and enable shorctus for them.
* Set shortcuts for 'Preferences...' and 'Quit' from settings on startup.
* Fixed #83: Add menu actions to main window.
* Fixed #93: Add 'Toggle Menu' and 'Preferences...' to context menu.
* Use GNUInstallDirs in CMakeLists.txt to stop hardcoding paths
* Make the left column expandable to get more space for translated text.
* Updated german translation
* Remove empty file
* Remove unnecessarily noisy qDebug calls
* Portuguese update
* Add Portuguese translation
* Update Russian translation
* slightly naive "layout/preset" implementation
* fixed build for Qt4 and Qt5.x < 5.2
* Rework settings window
* Fixed translation (added tr() for some combo boxes in properties dialog).
0.6.0 / 2014-10-21
==================
* Release 0.6.0
* Add an initial CONTRIBUTING document
* Update AUTHORS
* Update README
* Add an INSTALL file
* CMakeLists.txt cleanup
* Russian translation improvements.
* Updated translation.
* Desktop icon theme support Use icons from current desktop theme (Qt functionality) Reformat icons.qrc into theme format and fallback to the provided theme if no system theme present in main.cpp Add more action icons according to the XDG Icon Naming Specification
* fixed translation (some spelling, some inconsistencies, some bad wording) used other applications to determine common practice for some of the terms
* qctions refactored a bit; copy/paste etc. shortcuts work in subterminals finally
* fixed #80 Wronge state on startup
* fix translation of termwidget context menu
* add german translation
* fixed #65 Typo in QTerminal Properties window
* fixed #74 Zoom reset option resets font back to Monospace
* Check Ctrl manually on activateUrl signal
* Fix for #63
* Qt5 additional dependency and version number fix
* estonian translation
* Update termwidget.cpp
* Update termwidget.h
* Add Spanish translation
* Fixed install qterminal incon
* Simple profile support
0.5.0 / 2014-05-27
==================
* basic Qt5 port
* implemented #54 Add option to hide tab bar if only one tab is open
* set focus to current terminal after bookmark command applied
* Update Russian translation
* fixed #51 Shortcuts broken after menu hiding
* fixed #50 Bookmarks panel always shows, even if the bookmarks are disabled
* fixed #49 Only show monospace fonts in the font picker
* save bookmars widget visibility; fix crash in some config circumstances
* Include QApplication where needed. Fixes #47
* removed un-needed file
* changes required for new qtermwidget build/structure; includes fixed for qtermwidget Qt5 port
* bookmarks: key shortcut to open/close bookmarks widget
* bookmarks: saving/loading/editing
* initial support for extended bookmarks (read only for now)
* fixed #31 does not resize itself when screen resolution has changed
* implemented #41 Request: Ctrl+M Disable Menu Bar Option
* fix "save prefs on exit". Thanks Joseph A Philbrook for reporting and support ideas
* improvements for #28 Use system qxt-devel
* fixed #4 Open new tab in same working directory
* fixed #15 "Raw" -e params
* potential fix for height calculation regarding #31 does not resize itself when screen resolution has changed
* potential fix for screen size changed in drop down mode #31 does not resize itself when screen resolution has changed
* fixed #28 Use system qxt-devel
* fixed #37 Configuration AskOnExit should be editable via GUI
* Added Russian translation
* Clean up --help
* Don't forget highlight current terminal option
* fix #27 Ctrl+D on a new window closes all windows
* fix FSF address
* fixed #13 Window action names
* do not use conflicting shortcuts with vim/screen
* Added global tab rename (sessionRename) shortcut
* trivial shortcuts in a terminal-menu are a no-go because they ineterfere with several usual ncurses programs like nano, or weechat, even bash is interfered.
* allow only monospaced fonts in preferences dialog
* remove unused code in FindQTermWidget.cmake
* fixed main window ui file (manually edited probably) to work with designr again. Use "Preferences..." instead of "Configure QTerminal"
* compile also italian translations
* added italian translations
* get rid of contraproductive Ctrl-W to close a tab. Replaced that wieht Ctrl-Shift-W. Use nano in qterminal and try to search. You will see, what i mean ... * it takes a horizontal ruler to tile a terminal vertically and vice versa * make border of active terminal a litte bit thinner 3px -> 2px
* Added new action: "Paste Selection". Fixes #21
* Handle migration "Paste Selection"->"Paste Clipboard" in settings
* Rename PASTE_SELECTION to PASTE_CLIPBOARD which is what it does
* ctrl+n opens new window - reimplemented #19
* Added search functionality
* now with actual changes.
* fixed bad layout
* Reorganize menus (mostly fixes issue 8)
* Correction proposal for previous error
* Add zoom terminal. New option in PropertiesDialog
* return dropdown dsktop file because "desktop actions" are not supported almost anywhere
* Use standard utilities-terminal as default icon as a qterminal icon is not shipped
* Get rid of qterminal_drop.desktop, favouring a Desktop Action
* fixed #5 Tabs on top by default
* final fix for doubleclicks on tabwidget
* fixed #1 lost focus after close tab
* fix for lost custom tab labels when the tab is removed
* clear active terminal implemented
* wrong application domain fixed
* highlight current terminal is optional now
* fixed broken layouting from previous patches
* XDG standardized config place
* desktop files fixes
* install unix icon
* yakuake mode compile fix for X11
* build on mac
* Switch to Qxt global shortcut
* "make lupdate" implemented; do ot delete ts files on "make clean"; fix translator loading
* DropDown mode
* allow translations
* tabs to spaces
* allow moving of tabs
* Added History size properties
* desktop file for XDG
* fixed shortcut defaults as it used wrong int into strings
* reverted misunderstood spaces in keys - it's used in shorcut widget display
* remove ' ' from config keys as it makes config file unreadable
* LIB_SUFFIX autodiscovery
* Added missing translatable string. Shortcut tableview in preferences dialogue now resizes columns to fit contents Disabled verticalHeader on shorcut tableview. Added 'copy' and 'paste' to configurable shortcuts list. Removed '1.0' branding from windowTitle to read only 'QTerminal'.
* qmake pro file (easier to use in creator than cmake, figured i'd share.)
* Support for keyboard shortcuts; free-form text entry style.
* -e|--execute implemented; minor help fixes
* sync from experimental
* sync with experimental "bundle" repository
* standardized icons and keyboard shortcuts
* set minimal window size for initial resizing
* remove annoying "close session?" dialog
* all actions are available from mainwindow's menu
* mac icon fix
* bundle the qtermwidget's kb-layout files too
* initial support for apple bundles
* key shorcut unified for x11/mac
* actions cleanup
* fix for session closing
* fix for sub-terminals switching/focuses (to stay in current window/tab)
* small refactoring of methods duplicities
* transparency and open/save session shortcuts removed
* better highlight of the current subterminal (wide line)
* fixed focus handling again
* implementation of sub-terminal shitch key-shortcut
* highlight current subwindow (work in progress)
* set correct focus when (sub)terminal opens
* patches to build on BSD by Christopher VdoP
* correct closing on linux
* include fixes; editable gui
* split and collapse progress
* case sensitive includes
* sub-terminals splitting and collapsing
* allow to change emulation type
* docs;build fixes
* preferences are split into regular dialog
* termwidget split; properties separated
* actions texts standardized; all Qt styles supported in menu
* font handling fix for macosx
* macosx port; cmake support
* initial import

@ -1,244 +0,0 @@
cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)
project(qterminal)
include(GNUInstallDirs)
# qterminal version
set(STR_VERSION "0.9.0")
set(LXQTBT_MINIMUM_VERSION "0.5.0")
set(QTERMWIDGET_MINIMUM_VERSION "0.9.0")
option(UPDATE_TRANSLATIONS "Update source translation translations/*.ts files" OFF)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
# we need qpa/qplatformnativeinterface.h for global shortcut
find_package(Qt5Gui REQUIRED)
find_package(Qt5Widgets REQUIRED)
find_package(Qt5LinguistTools REQUIRED)
if(APPLE)
elseif(UNIX)
find_package(Qt5X11Extras REQUIRED)
find_package(Qt5DBus)
endif()
find_package(QTermWidget5 ${QTERMWIDGET_MINIMUM_VERSION} REQUIRED)
find_package(lxqt-build-tools ${LXQTBT_MINIMUM_VERSION} REQUIRED)
include(LXQtPreventInSourceBuilds)
include(LXQtTranslateTs)
include(LXQtCompilerSettings NO_POLICY_SCOPE)
message(STATUS "Qt version: ${Qt5Core_VERSION}")
# TODO remove Qxt
message(STATUS "Using bundled Qxt...")
set(QXT_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/src/third-party")
if(APPLE)
find_library(CARBON_LIBRARY Carbon REQUIRED)
message(STATUS "CARBON_LIBRARY: ${CARBON_LIBRARY}")
elseif(UNIX)
find_package(X11 REQUIRED)
message(STATUS "X11_X11_LIB: ${X11_X11_LIB}")
endif()
add_definitions(
-DSTR_VERSION=\"${STR_VERSION}\"
-DQT_NO_FOREACH
)
set(EXE_NAME qterminal)
set(QTERM_SRC
src/main.cpp
src/mainwindow.cpp
src/tabbar.cpp
src/tabwidget.cpp
src/termwidget.cpp
src/termwidgetholder.cpp
src/terminalconfig.cpp
src/properties.cpp
src/propertiesdialog.cpp
src/bookmarkswidget.cpp
src/fontdialog.cpp
src/dbusaddressable.cpp
)
set(QTERM_MOC_SRC
src/qterminalapp.h
src/mainwindow.h
src/tabbar.h
src/tabwidget.h
src/termwidget.h
src/termwidgetholder.h
src/propertiesdialog.h
src/bookmarkswidget.h
src/fontdialog.h
)
if (Qt5DBus_FOUND)
add_definitions(-DHAVE_QDBUS)
QT5_ADD_DBUS_ADAPTOR(QTERM_SRC src/org.lxqt.QTerminal.Window.xml mainwindow.h MainWindow)
QT5_ADD_DBUS_ADAPTOR(QTERM_SRC src/org.lxqt.QTerminal.Tab.xml termwidgetholder.h TermWidgetHolder)
QT5_ADD_DBUS_ADAPTOR(QTERM_SRC src/org.lxqt.QTerminal.Terminal.xml termwidget.h TermWidget)
QT5_ADD_DBUS_ADAPTOR(QTERM_SRC src/org.lxqt.QTerminal.Process.xml qterminalapp.h QTerminalApp)
set(QTERM_MOC_SRC ${QTERM_MOC_SRC} src/dbusaddressable.h)
message(STATUS "Building with Qt5DBus support")
endif()
if(NOT QXT_FOUND)
set(QTERM_SRC ${QTERM_SRC} src/third-party/qxtglobalshortcut.cpp)
set(QTERM_MOC_SRC ${QTERM_MOC_SRC} src/third-party/qxtglobalshortcut.h)
if(WIN32)
set(QTERM_SRC ${QTERM_SRC} src/third-party/qxtglobalshortcut_win.cpp)
elseif(APPLE)
set(QTERM_SRC ${QTERM_SRC} src/third-party/qxtglobalshortcut_mac.cpp)
else()
set(QTERM_SRC ${QTERM_SRC} src/third-party/qxtglobalshortcut_x11.cpp)
endif()
endif()
set(QTERM_UI_SRC
src/forms/qterminal.ui
src/forms/propertiesdialog.ui
src/forms/bookmarkswidget.ui
src/forms/fontdialog.ui
)
set(QTERM_RCC_SRC
src/icons.qrc
)
qt5_wrap_ui( QTERM_UI ${QTERM_UI_SRC} )
qt5_wrap_cpp( QTERM_MOC ${QTERM_MOC_SRC} )
qt5_add_resources( QTERM_RCC ${QTERM_RCC_SRC} )
lxqt_translate_ts(QTERM_QM
UPDATE_TRANSLATIONS
${UPDATE_TRANSLATIONS}
SOURCES
${QTERM_SRC}
${QTERM_UI_SRC}
${QTERM_MOC_SRC}
TRANSLATION_DIR "src/translations"
PULL_TRANSLATIONS
${PULL_TRANSLATIONS}
CLEAN_TRANSLATIONS
${CLEAN_TRANSLATIONS}
TRANSLATIONS_REPO
${TRANSLATIONS_REPO}
TRANSLATIONS_REFSPEC
${TRANSLATIONS_REFSPEC}
)
include_directories(
"${PROJECT_SOURCE_DIR}"
"${PROJECT_SOURCE_DIR}/src"
"${PROJECT_BINARY_DIR}"
${QXT_INCLUDE_DIRS}
)
if(X11_FOUND)
include_directories("${X11_INCLUDE_DIR}")
endif()
# TODO/FIXME: apple bundle
set(GUI_TYPE "")
set(APPLE_BUNDLE_SOURCES "")
if(APPLEBUNDLE)
add_definitions(-DAPPLE_BUNDLE)
set(GUI_TYPE MACOSX_BUNDLE)
# create Info.plist file
set(MACOSX_BUNDLE_ICON_FILE qterminal.icns)
set(MACOSX_BUNDLE_INFO_STRING "QTerminal ${STR_VERSION}")
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.qterminal")
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${STR_VERSION}")
set(MACOSX_BUNDLE_BUNDLE_NAME "${EXE_NAME}")
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${STR_VERSION}")
set(MACOSX_BUNDLE_BUNDLE_VERSION "${STR_VERSION}")
set(MACOSX_BUNDLE_COPYRIGHT "(c) Petr Vanek &lt;petr@yarpen.cz&gt;")
set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/macosx/qterminal.icns"
PROPERTIES MACOSX_PACKAGE_LOCATION Resources
)
# use icon for app bundle to be visible in finder
set(APPLE_BUNDLE_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/macosx/qterminal.icns")
else()
set(TRANSLATIONS_DIR "${CMAKE_INSTALL_FULL_DATADIR}/qterminal/translations")
add_definitions(-DTRANSLATIONS_DIR=\"${TRANSLATIONS_DIR}\")
endif()
add_executable(${EXE_NAME} ${GUI_TYPE}
${QTERM_SRC}
${QTERM_UI}
${QTERM_MOC}
${QTERM_RCC}
${APPLE_BUNDLE_SOURCES}
${QTERM_QM}
)
target_link_libraries(${EXE_NAME}
Qt5::Gui
qtermwidget5
util
)
if(QXT_FOUND)
target_link_libraries(${EXE_NAME} ${QXT_CORE_LIB} ${QXT_GUI_LIB})
endif()
if (Qt5DBus_FOUND)
target_link_libraries(${EXE_NAME} ${Qt5DBus_LIBRARIES})
endif()
if(APPLE)
target_link_libraries(${EXE_NAME} ${CARBON_LIBRARY})
elseif(UNIX)
target_link_libraries(${EXE_NAME} Qt5::X11Extras)
endif()
if(X11_FOUND)
target_link_libraries(${EXE_NAME} ${X11_X11_LIB})
endif()
install(FILES
qterminal.desktop
qterminal_drop.desktop
DESTINATION "${CMAKE_INSTALL_DATADIR}/applications"
)
install(FILES
qterminal.appdata.xml
DESTINATION "${CMAKE_INSTALL_DATADIR}/appdata"
)
if(NOT APPLEBUNDLE)
install(TARGETS ${EXE_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
install(FILES ${QTERM_QM} DESTINATION ${TRANSLATIONS_DIR})
install(FILES src/icons/qterminal.png DESTINATION "${CMAKE_INSTALL_DATADIR}/icons/hicolor/64x64/apps")
else()
message(STATUS "APPLEBUNDLE")
install(CODE "message(STATUS \"Cleaning previously installed bundle (rm -r)\")")
install(CODE "execute_process(COMMAND rm -r ${CMAKE_INSTALL_PREFIX}/${EXE_NAME}.app)")
install(TARGETS ${EXE_NAME} DESTINATION "${CMAKE_INSTALL_PREFIX}")
# helper stuff to create real apple bundle.
# Black magic is summoned here...
if(APPLEBUNDLE_STANDALONE)
message(STATUS "APPLEBUNDLE_STANDALONE")
configure_file("${CMAKE_SOURCE_DIR}/bundle.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/bundle.cmake" @ONLY)
install(SCRIPT "${CMAKE_SOURCE_DIR}/bundle.cmake")
endif()
# bundle required keytabs from the qtermwidget package as well
install(CODE "message(STATUS \"Bundling (cp) keytab files from ${QTERMWIDGET_SHARE}/qtermwidget/\")")
install(CODE "execute_process(COMMAND cp -r ${QTERMWIDGET_SHARE}/qtermwidget/ ${CMAKE_INSTALL_PREFIX}/${EXE_NAME}.app/Contents/Resources)")
install(FILES ${QTERM_QM} DESTINATION ${CMAKE_INSTALL_PREFIX}/${EXE_NAME}.app/Contents/translations)
endif()

@ -1,23 +0,0 @@
# Bug reports
Please file bugs on the qterminal github tracker:
https://github.com/lxqt/qterminal/issues
Please file qtermwidget-related bugs on the qtermwidget github tracker:
https://github.com/lxqt/qtermwidget/issues
# Code contributions
For all code contributions, please open a pull request on Github:
https://github.com/lxde/qterminal/
Make sure your code is clean, devoid of debug statements and respects the style
of the rest of the file (including line length and indentation).
Do not pollute the git history with unnecessary commits! Make sure each of your
commits compiles to ensure ease of bisection and have clear separation of one
feature or bugfix per commit.
Please also make sure you set your `git.name` and `git.email` options properly:
https://help.github.com/articles/setting-your-email-in-git/

1630
Doxyfile

File diff suppressed because it is too large Load Diff

@ -1,280 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS

@ -1,25 +0,0 @@
# QTerminal
## Overview
QTerminal is a lightweight Qt terminal emulator based on [QTermWidget](https://github.com/lxqt/qtermwidget).
It is maintained by the LXQt project but can be used independently from this desktop environment. The only bonds are [lxqt-build-tools](https://github.com/lxqt/lxqt-build-tools) representing a build dependency and the localization files which were outsourced to LXQt repository [lxqt-l10n](https://github.com/lxqt/lxqt-l10n).
This project is licensed under the terms of the [GPLv2](https://www.gnu.org/licenses/gpl-2.0.en.html) or any later version. See the LICENSE file for the full text of the license.
## Installation
### Compiling sources
Dependencies are qtx11extras ≥ 5.2 and [QTermWidget](https://github.com/lxqt/qtermwidget).
In order to build CMake ≥ 3.0.2 and [lxqt-build-tools](https://github.com/lxqt/lxqt-build-tools) are needed as well as optionally Git to pull latest VCS checkouts. The localization files were outsourced to repository [lxqt-l10n](https://github.com/lxqt/lxqt-l10n) so the corresponding dependencies are needed, too. Please refer to this repository's `README.md` for further information.
Code configuration is handled by CMake. Building out of source is required. CMake variable `CMAKE_INSTALL_PREFIX` will normally have to be set to `/usr`.
To build run `make`, to install `make install` which accepts variable `DESTDIR` as usual.
### Binary packages
QTerminal is provided by all major Linux distributions like [Arch Linux](https://www.archlinux.org/packages/?q=qterminal), Debian (as of Debian stretch), Fedora and openSUSE.
Just use the distributions' package managers to search for string `qterminal`.

@ -1,43 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<application>
<id type="desktop">qterminal.desktop</id>
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-2</project_license>
<name>QTerminal</name>
<summary>A lightweight multiplatform terminal emulator.</summary>
<description>
<p>
QTerminal is a lightweight multiplatform terminal emulator.
</p>
<p>
Its main features are:
</p>
<ul>
<li>Multiple tabs</li>
<li>Layout terminals side-by-side</li>
<li>Dropdown mode</li>
<li>Text search</li>
<li>Configurable uster interface</li>
<li>Integration of system clipboard</li>
</ul>
</description>
<screenshots>
<screenshot type="default">
<image>http://worblehat.github.io/storage/qterminal_1.png</image>
<caption>The default QTerminal window.</caption>
</screenshot>
</screenshots>
<screenshots>
<screenshot type="default">
<image>http://worblehat.github.io/storage/qterminal_2.png</image>
<caption>QTerminal with multiple tabs, splitted terminals and highlighted text.</caption>
</screenshot>
</screenshots>
<screenshots>
<screenshot type="default">
<image>http://worblehat.github.io/storage/qterminal_3.png</image>
<caption>Find bar and highlighted match.</caption>
</screenshot>
</screenshots>
<url type="homepage">https://github.com/lxqt/qterminal</url>
</application>

@ -1,65 +0,0 @@
[Desktop Entry]
Name=QTerminal
Type=Application
GenericName=Terminal emulator
GenericName[es]=Emulador de terminal
Comment=Terminal emulator
Comment[ca]=Emulador de terminal
Comment[de]=Befehlszeile verwenden
Comment[el]=Προσομοιωτής τερματικού
Comment[es]=Emulador de terminal
Comment[fr]=Terminal
Comment[lt]=Terminalo emuliatorius
Comment[pl]=Emulator terminala
Comment[pt]=Emulador de terminal
Comment[pt_BR]=Emulador de terminal
Comment[ru_RU]=Эмулятор терминала
Comment[ja]=ターミナル エミュレータ
Icon=utilities-terminal
Exec=qterminal
Terminal=false
Categories=Qt;System;TerminalEmulator;
Actions=Dropdown;
[Desktop Action Dropdown]
Name=Drop-down terminal
Exec=qterminal --drop
Icon=utilities-terminal
Name[en_GB]=Drop-down Terminal
Name[bg]=Падащ терминал
Name[ca]=Terminal desplegable
Name[ca@valencia]=Terminal desplegable
Name[cs]=Vysouvací terminál
Name[da]=Terminal der ruller ned
Name[de]=Aufklapp-Terminal
Name[el]=Αναπτυσσόμενο τερματικό
Name[es]=Terminal desplegable
Name[et]=Lahtikeriv terminal
Name[fr]=Terminal déroulant
Name[hr]=Spuštajući terminal
Name[hu]=Legördülő terminál
Name[it]=Terminale a discesa
Name[ja]=ドロップダウン式ターミナル
Name[km]=ស្ថានីយ​ទម្លាក់​ចុះ
Name[ko]=위에서 내려오는 터미널
Name[lt]=Išskleidžiamasis terminalas
Name[nb]=Nedtrekksterminal
Name[nds]=Utklapp-Konsool
Name[nl]=Uitvouwbare terminalemulator
Name[pa]=ਲਟਕਦਾ ਟਰਮੀਨਲ
Name[pl]=Rozwijany emulator terminala
Name[pt]=Terminal suspenso
Name[pt_BR]=Terminal suspenso
Name[ro]=Terminal derulant
Name[ru]=Выпадающий терминал
Name[sk]=Rozbaľovací terminál
Name[sv]=Rullgardinsterminal
Name[th]=เทอร์มินัลแบบหย่อนลง
Name[tr]=Yukarıdan Açılan Uçbirim
Name[uk]=Спадний термінал
Name[x-test]=xxDrop-down Terminalxx
Name[zh_CN]=拉幕式终端
Name[zh_TW]=下拉式終端機

@ -1,53 +0,0 @@
TARGET = qterminal
TEMPLATE = app
# qt5 only. Please use cmake - it's an official build tool for this software
QT += widgets
CONFIG += link_pkgconfig \
depend_includepath
PKGCONFIG += qtermwidget5
DEFINES += STR_VERSION=\\\"0.9.0\\\"
SOURCES += $$files(src/*.cpp)
HEADERS += $$files(src/*.h)
INCLUDEPATH += src
INCLUDEPATH += src/third-party
SOURCES += src/third-party/qxtglobalshortcut.cpp
HEADERS += src/third-party/qxtglobalshortcut.h
HEADERS += src/third-party/qxtglobalshortcut_p.h
win32 {
SOURCES += src/third-party/qxtglobalshortcut_win.cpp
}
unix:!macx {
SOURCES += src/third-party/qxtglobalshortcut_x11.cpp
LIBS += -L/usr/X11/lib -lX11
QT += x11extras
}
macx: {
SOURCES += src/third-party/qxtglobalshortcut_mac.cpp
}
RESOURCES += src/icons.qrc
FORMS += $$files(src/forms/*.ui)
unix {
isEmpty(PREFIX) {
PREFIX = /usr/local
}
BINDIR = $$PREFIX/bin
INSTALLS += target shortcut
target.path = $$BINDIR
DATADIR = $$PREFIX/share
shortcut.path = $$DATADIR/applications
shortcut.files = qterminal.desktop
}

@ -1,66 +0,0 @@
[Desktop Entry]
Type=Application
Exec=qterminal --drop
Terminal=false
Categories=Qt;System;TerminalEmulator;
Icon=utilities-terminal
Name=QTerminal drop down
Name[ca]=QTerminal desplegable
Name[de]=QTerminal herabhängend
Name[el]=QTerminal αναπτυσσόμενο
Name[es]=QTerminal desplegable
Name[lt]=QTerminal išskleidžiamasis
Name[pl]=QTerminal (tryb rozwijany)
Name[pt]=QTerminal suspenso
Name[pt_BR]=QTerminal suspenso
Name[ja]=QTerminal ドロップダウン
GenericName=Drop-down Terminal
GenericName[bg]=Падащ терминал
GenericName[ca]=Terminal desplegable
GenericName[ca@valencia]=Terminal desplegable
GenericName[cs]=Vysouvací terminál
GenericName[da]=Terminal der ruller ned
GenericName[de]=Aufklapp-Terminal
GenericName[el]=Αναπτυσσόμενο τερματικό
GenericName[en_GB]=Drop-down Terminal
GenericName[es]=Terminal desplegable
GenericName[et]=Lahtikeriv terminal
GenericName[fr]=Terminal déroulant
GenericName[hr]=Spuštajući terminal
GenericName[hu]=Legördülő terminál
GenericName[it]=Terminale a discesa
GenericName[ja]=ドロップダウン式ターミナル
GenericName[km]=ស្ថានីយ​ទម្លាក់​ចុះ
GenericName[ko]=위에서 내려오는 터미널
GenericName[lt]=Išskleidžiamasis terminalas
GenericName[nb]=Nedtrekksterminal
GenericName[nds]=Utklapp-Konsool
GenericName[nl]=Uitvouwbare terminalemulator
GenericName[pa]=ਲਟਕਦਾ ਟਰਮੀਨਲ
GenericName[pl]=Rozwijany emulator terminala
GenericName[pt]=Terminal suspenso
GenericName[pt_BR]=Terminal suspenso
GenericName[ro]=Terminal derulant
GenericName[ru]=Выпадающий терминал
GenericName[sk]=Rozbaľovací terminál
GenericName[sv]=Rullgardinsterminal
GenericName[th]=เทอร์มินัลแบบหย่อนลง
GenericName[tr]=Yukarıdan Açılan Uçbirim
GenericName[uk]=Спадний термінал
GenericName[x-test]=xxDrop-down Terminalxx
GenericName[zh_CN]=拉幕式终端
GenericName[zh_TW]=下拉式終端機
Comment=A drop-down terminal emulator.
Comment[ca]=Un emulador de terminal desplegable.
Comment[de]=Ein Ausklapp-Terminalemulator.
Comment[el]=Ένας αναπτυσσόμενος προσομοιωτής τερματικού.
Comment[es]=Un emulador de terminal desplegable.
Comment[lt]=Išskleidžiamasis terminalo emuliatorius.
Comment[pt]=Um emulador de terminal suspenso.
Comment[pt_BR]=Um emulador de terminal suspenso.
Comment[ru]=Выпадающий эмулятор терминала.
Comment[ja]=ドロップダウン式 ターミナルエミュレータ

@ -1,397 +0,0 @@
/***************************************************************************
* Copyright (C) 2014 by Petr Vanek *
* petr@scribus.info *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include <QDebug>
#include <QStandardPaths>
#include "bookmarkswidget.h"
#include "properties.h"
#include "config.h"
class AbstractBookmarkItem
{
public:
enum ItemType {
Root = 0,
Group = 1,
Command = 2
};
AbstractBookmarkItem(AbstractBookmarkItem* parent = 0)
{
m_parent = parent;
}
~AbstractBookmarkItem()
{
qDeleteAll(m_children);
}
ItemType type() { return m_type; }
QString value() { return m_value; }
QString display() { return m_display; }
void addChild(AbstractBookmarkItem* item) { m_children << item; }
int childCount() { return m_children.count(); }
QList<AbstractBookmarkItem*> children() { return m_children; }
AbstractBookmarkItem *child(int number) { return m_children.value(number); }
AbstractBookmarkItem *parent() { return m_parent; }
int childNumber() const
{
if (m_parent)
return m_parent->children().indexOf(const_cast<AbstractBookmarkItem*>(this));
return 0;
}
protected:
ItemType m_type;
AbstractBookmarkItem *m_parent;
QList<AbstractBookmarkItem*> m_children;
QString m_value;
QString m_display;
};
class BookmarkRootItem : public AbstractBookmarkItem
{
public:
BookmarkRootItem()
: AbstractBookmarkItem()
{
m_type = AbstractBookmarkItem::Root;
m_value = m_display = "root";
}
};
class BookmarkCommandItem : public AbstractBookmarkItem
{
public:
BookmarkCommandItem(const QString &name, const QString &command, AbstractBookmarkItem *parent)
: AbstractBookmarkItem(parent)
{
m_type = AbstractBookmarkItem::Command;
m_value = command;
m_display = name;
}
};
class BookmarkGroupItem : public AbstractBookmarkItem
{
public:
BookmarkGroupItem(const QString &name, AbstractBookmarkItem *parent)
: AbstractBookmarkItem(parent)
{
m_type = AbstractBookmarkItem::Group;
m_display = name;
}
};
class BookmarkLocalGroupItem : public BookmarkGroupItem
{
public:
BookmarkLocalGroupItem(AbstractBookmarkItem *parent)
: BookmarkGroupItem(QObject::tr("Local Bookmarks"), parent)
{
QList<QStandardPaths::StandardLocation> locations;
locations << QStandardPaths::DesktopLocation
<< QStandardPaths::DocumentsLocation
<< QStandardPaths::TempLocation
<< QStandardPaths::HomeLocation
<< QStandardPaths::MusicLocation
<< QStandardPaths::PicturesLocation;
QString path;
QString name;
QString cmd;
QDir d;
// standard $HOME subdirs
for (const QStandardPaths::StandardLocation i : qAsConst(locations))
{
path = QStandardPaths::writableLocation(i);
if (!d.exists(path))
{
continue;
}
name = QStandardPaths::displayName(i);
path.replace(" ", "\\ ");
cmd = "cd " + path;
addChild(new BookmarkCommandItem(name, cmd, this));
}
// system env - include dirs in the tree
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
const auto keys = env.keys();
for (const QString &i : keys)
{
path = env.value(i);
if (!d.exists(path) || !QFileInfo(path).isDir())
{
continue;
}
path.replace(" ", "\\ ");
cmd = "cd " + path;
addChild(new BookmarkCommandItem(i, cmd, this));
}
}
};
class BookmarkFileGroupItem : public BookmarkGroupItem
{
// hierarchy handling
// m_pos to group map. Example: group1.group2=item
QHash<QString,AbstractBookmarkItem*> m_map;
// current position level. Example "group1", "group2"
QStringList m_pos;
public:
BookmarkFileGroupItem(AbstractBookmarkItem *parent, const QString &fname)
: BookmarkGroupItem(QObject::tr("Synchronized Bookmarks"), parent)
{
QFile f(fname);
if (!f.open(QIODevice::ReadOnly))
{
qDebug() << "Canot open file" << fname;
// TODO/FIXME: message box
return;
}
QXmlStreamReader xml;
xml.setDevice(&f);
while (true)
{
xml.readNext();
switch (xml.tokenType())
{
case QXmlStreamReader::StartElement:
{
AbstractBookmarkItem *parent = m_map.contains(xmlPos()) ? m_map[xmlPos()] : this;
QString tag = xml.name().toString();
if (tag == "group")
{
QString name = xml.attributes().value("name").toString();
m_pos.append(name);
BookmarkGroupItem *i = new BookmarkGroupItem(name, parent);
parent->addChild(i);
m_map[xmlPos()] = i;
}
else if (tag == "command")
{
QString name = xml.attributes().value("name").toString();
QString cmd = xml.attributes().value("value").toString();
BookmarkCommandItem *i = new BookmarkCommandItem(name, cmd, parent);
parent->addChild(i);
}
break;
}
case QXmlStreamReader::EndElement:
{
QString tag = xml.name().toString();
if (tag == "group")
{
m_pos.removeLast();
}
break;
}
case QXmlStreamReader::Invalid:
qDebug() << "XML error: " << xml.errorString().constData()
<< xml.lineNumber() << xml.columnNumber();
m_map.clear();
return;
case QXmlStreamReader::EndDocument:
m_map.clear();
return;
default:
break;
} // switch
} // while
} // constructor
QString xmlPos()
{
return m_pos.join(".");
}
};
BookmarksModel::BookmarksModel(QObject *parent)
: QAbstractItemModel(parent),
m_root(0)
{
setup();
}
void BookmarksModel::setup()
{
if (m_root)
delete m_root;
m_root = new BookmarkRootItem();
m_root->addChild(new BookmarkLocalGroupItem(m_root));
m_root->addChild(new BookmarkFileGroupItem(m_root, Properties::Instance()->bookmarksFile));
beginResetModel();
endResetModel();
}
BookmarksModel::~BookmarksModel()
{
if (m_root)
delete m_root;
}
int BookmarksModel::columnCount(const QModelIndex & /* parent */) const
{
return 2;
}
QVariant BookmarksModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
switch (role)
{
case Qt::DisplayRole:
case Qt::EditRole:
return index.column() == 0 ? getItem(index)->display() : getItem(index)->value();
case Qt::FontRole:
{
QFont f;
if (static_cast<AbstractBookmarkItem*>(index.internalPointer())->type() == AbstractBookmarkItem::Group)
{
f.setBold(true);
}
return f;
}
default:
return QVariant();
}
}
AbstractBookmarkItem *BookmarksModel::getItem(const QModelIndex &index) const
{
if (index.isValid())
{
AbstractBookmarkItem *item = static_cast<AbstractBookmarkItem*>(index.internalPointer());
if (item)
return item;
}
return m_root;
}
QVariant BookmarksModel::headerData(int section, Qt::Orientation orientation,
int role) const
{
return QVariant();
}
QModelIndex BookmarksModel::index(int row, int column, const QModelIndex &parent) const
{
if (parent.isValid() && parent.column() != 0)
return QModelIndex();
AbstractBookmarkItem *parentItem = getItem(parent);
AbstractBookmarkItem *childItem = parentItem->child(row);
if (childItem)
return createIndex(row, column, childItem);
else
return QModelIndex();
}
QModelIndex BookmarksModel::parent(const QModelIndex &index) const
{
if (!index.isValid())
return QModelIndex();
AbstractBookmarkItem *childItem = getItem(index);
AbstractBookmarkItem *parentItem = childItem->parent();
if (parentItem == m_root)
return QModelIndex();
return createIndex(parentItem->childNumber(), 0, parentItem);
}
int BookmarksModel::rowCount(const QModelIndex &parent) const
{
AbstractBookmarkItem *parentItem = getItem(parent);
return parentItem->childCount();
}
#if 0
bool BookmarksModel::setData(const QModelIndex &index, const QVariant &value,
int role)
{
if (role != Qt::EditRole)
return false;
AbstractBookmarkItem *item = getItem(index);
bool result = item->setData(index.column(), value);
if (result)
emit dataChanged(index, index);
return result;
}
#endif
BookmarksWidget::BookmarksWidget(QWidget *parent)
: QWidget(parent)
{
setupUi(this);
m_model = new BookmarksModel(this);
treeView->setModel(m_model);
treeView->header()->hide();
connect(treeView, &QTreeView::doubleClicked,
this, &BookmarksWidget::handleCommand);
}
BookmarksWidget::~BookmarksWidget()
{
}
void BookmarksWidget::setup()
{
m_model->setup();
treeView->expandAll();
treeView->resizeColumnToContents(0);
treeView->resizeColumnToContents(1);
}
void BookmarksWidget::handleCommand(const QModelIndex& index)
{
AbstractBookmarkItem *item = static_cast<AbstractBookmarkItem*>(index.internalPointer());
if (!item || item->type() != AbstractBookmarkItem::Command)
return;
emit callCommand(item->value() + "\n"); // TODO/FIXME: decide how to handle EOL
}

@ -1,76 +0,0 @@
/***************************************************************************
* Copyright (C) 2014 by Petr Vanek *
* petr@scribus.info *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef BOOKMARKSWIDGET_H
#define BOOKMARKSWIDGET_H
#include "ui_bookmarkswidget.h"
class AbstractBookmarkItem;
class BookmarksModel;
class BookmarksWidget : public QWidget, Ui::BookmarksWidget
{
Q_OBJECT
public:
BookmarksWidget(QWidget *parent=NULL);
~BookmarksWidget();
void setup();
signals:
void callCommand(const QString &cmd);
private:
BookmarksModel *m_model;
private slots:
void handleCommand(const QModelIndex& index);
};
class BookmarksModel : public QAbstractItemModel
{
Q_OBJECT
public:
BookmarksModel(QObject *parent = 0);
~BookmarksModel();
void setup();
QVariant data(const QModelIndex &index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const;
QModelIndex index(int row, int column,
const QModelIndex &parent = QModelIndex()) const;
QModelIndex parent(const QModelIndex &index) const;
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
private:
AbstractBookmarkItem *getItem(const QModelIndex &index) const;
AbstractBookmarkItem *m_root;
};
#endif

@ -1,120 +0,0 @@
/***************************************************************************
* Copyright (C) 2006 by Vladimir Kuznetsov *
* vovanec@gmail.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef CONFIG_H
#define CONFIG_H
#define ADD_TAB "Add Tab"
#define RENAME_TAB "Rename Tab"
#define CLOSE_TAB "Close Tab"
#define NEW_WINDOW "New Window"
#define QUIT "Quit"
#define PREFERENCES "Preferences..."
#define TAB_NEXT "Next Tab"
#define TAB_PREV "Previous Tab"
#define CLEAR_TERMINAL "Clear Active Terminal"
#define SPLIT_HORIZONTAL "Split Terminal Horizontally"
#define SPLIT_VERTICAL "Split Terminal Vertically"
#define SUB_COLLAPSE "Collapse Subterminal"
#define SUB_LEFT "Left Subterminal"
#define SUB_RIGHT "Right Subterminal"
#define SUB_TOP "Top Subterminal"
#define SUB_BOTTOM "Bottom Subterminal"
#define MOVE_LEFT "Move Tab Left"
#define MOVE_RIGHT "Move Tab Right"
#define COPY_SELECTION "Copy Selection"
#define PASTE_CLIPBOARD "Paste Clipboard"
#define PASTE_SELECTION "Paste Selection"
#define ZOOM_IN "Zoom in"
#define ZOOM_OUT "Zoom out"
#define ZOOM_RESET "Zoom reset"
#define FIND "Find"
#define TOGGLE_MENU "Toggle Menu"
#define TOGGLE_BOOKMARKS "Toggle Bookmarks"
#define HIDE_WINDOW_BORDERS "Hide Window Borders"
#define SHOW_TAB_BAR "Show Tab Bar"
#define RENAME_SESSION "Rename Session"
#define FULLSCREEN "Fullscreen"
/* Some defaults for QTerminal application */
#define DEFAULT_WIDTH 800
#define DEFAULT_HEIGHT 600
#define DEFAULT_FONT "Monospace"
// ACTIONS
#define CLEAR_TERMINAL_SHORTCUT "Ctrl+Shift+X"
#define TAB_PREV_SHORTCUT "Ctrl+PgUp|Ctrl+Shift+Tab"
#define TAB_NEXT_SHORTCUT "Ctrl+PgDown|Ctrl+Tab"
#define SUB_BOTTOM_SHORTCUT "Alt+Down"
#define SUB_TOP_SHORTCUT "Alt+Up"
#define SUB_LEFT_SHORTCUT "Alt+Left"
#define SUB_RIGHT_SHORTCUT "Alt+Right"
#ifdef Q_WS_MAC
// It's tricky - Ctrl is "command" key on mac's keyboards
#define COPY_SELECTION_SHORTCUT "Ctrl+C"
#define PASTE_CLIPBOARD_SHORTCUT "Ctrl+V"
#define FIND_SHORTCUT "Ctrl+F"
#define NEW_WINDOW_SHORTCUT "Ctrl+N"
#define ADD_TAB_SHORTCUT "Ctrl+T"
#define CLOSE_TAB_SHORTCUT "Ctrl+W"
#define TOGGLE_MENU_SHORTCUT "Ctrl+M"
#define TOGGLE_BOOKMARKS_SHORTCUT "Ctrl+B"
#else
#define COPY_SELECTION_SHORTCUT "Ctrl+Shift+C"
#define PASTE_CLIPBOARD_SHORTCUT "Ctrl+Shift+V"
#define PASTE_SELECTION_SHORTCUT "Shift+Ins"
#define FIND_SHORTCUT "Ctrl+Shift+F"
#define NEW_WINDOW_SHORTCUT "Ctrl+Shift+N"
#define ADD_TAB_SHORTCUT "Ctrl+Shift+T"
#define CLOSE_TAB_SHORTCUT "Ctrl+Shift+W"
#define TOGGLE_MENU_SHORTCUT "Ctrl+Shift+M"
#define TOGGLE_BOOKMARKS_SHORTCUT "Ctrl+Shift+B"
#endif
#define ZOOM_IN_SHORTCUT "Ctrl++"
#define ZOOM_OUT_SHORTCUT "Ctrl+-"
#define ZOOM_RESET_SHORTCUT "Ctrl+0"
#define MOVE_LEFT_SHORTCUT "Shift+Alt+Left|Ctrl+Shift+PgUp"
#define MOVE_RIGHT_SHORTCUT "Shift+Alt+Right|Ctrl+Shift+PgDown"
#define RENAME_SESSION_SHORTCUT "Shift+Alt+S"
#define FULLSCREEN_SHORTCUT "F11"
// XON/XOFF features:
#define FLOW_CONTROL_ENABLED false
#define FLOW_CONTROL_WARNING_ENABLED false
#endif

@ -1,25 +0,0 @@
#include "dbusaddressable.h"
#ifdef HAVE_QDBUS
Q_DECLARE_METATYPE(QList<QDBusObjectPath>)
QString DBusAddressable::getDbusPathString()
{
return m_path;
}
QDBusObjectPath DBusAddressable::getDbusPath()
{
return QDBusObjectPath(m_path);
}
#endif
DBusAddressable::DBusAddressable(QString prefix)
{
#ifdef HAVE_QDBUS
QString uuidString = QUuid::createUuid().toString();
m_path = prefix + "/" + uuidString.replace(QRegExp("[\\{\\}\\-]"), "");
#endif
}

@ -1,34 +0,0 @@
#ifndef DBUSADDRESSABLE_H
#define DBUSADDRESSABLE_H
#include <QString>
#ifdef HAVE_QDBUS
#include <QtDBus/QtDBus>
#include <QUuid>
#endif
class DBusAddressable
{
#ifdef HAVE_QDBUS
private:
QString m_path;
#endif
public:
#ifdef HAVE_QDBUS
QDBusObjectPath getDbusPath();
QString getDbusPathString();
#endif
DBusAddressable(QString prefix);
};
#ifdef HAVE_QDBUS
template <class AClass, class WClass> void registerAdapter(WClass *obj)
{
new AClass(obj);
QString path = dynamic_cast<DBusAddressable*>(obj)->getDbusPathString();
QDBusConnection::sessionBus().registerObject(path, obj);
}
#endif
#endif

@ -1,63 +0,0 @@
/***************************************************************************
* Copyright (C) 2014 by Petr Vanek *
* petr@scribus.info *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include "fontdialog.h"
FontDialog::FontDialog(const QFont &f)
: QDialog(0)
{
setupUi(this);
fontComboBox->setFontFilters(QFontComboBox::MonospacedFonts
| QFontComboBox::NonScalableFonts
| QFontComboBox::ScalableFonts);
fontComboBox->setCurrentFont(f);
fontComboBox->setEditable(false);
sizeSpinBox->setValue(f.pointSize());
setFontSample(f);
connect(fontComboBox, &QFontComboBox::currentFontChanged,
this, &FontDialog::setFontSample);
connect(sizeSpinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
this, &FontDialog::setFontSize);
}
QFont FontDialog::getFont()
{
QFont f = fontComboBox->currentFont();
f.setPointSize(sizeSpinBox->value());
return f;
}
void FontDialog::setFontSample(const QFont &f)
{
previewLabel->setFont(f);
QString sample("%1 %2 pt");
previewLabel->setText(sample.arg(f.family()).arg(f.pointSize()));
}
void FontDialog::setFontSize()
{
const QFont &f = getFont();
previewLabel->setFont(f);
QString sample("%1 %2 pt");
previewLabel->setText(sample.arg(f.family()).arg(f.pointSize()));
}

@ -1,40 +0,0 @@
/***************************************************************************
* Copyright (C) 2014 by Petr Vanek *
* petr@scribus.info *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef FONT_DIALOG
#define FONT_DIALOG
#include "ui_fontdialog.h"
#include "properties.h"
class FontDialog : public QDialog, public Ui::FontDialog
{
Q_OBJECT
public:
FontDialog(const QFont &f);
QFont getFont();
private slots:
void setFontSample(const QFont &f);
void setFontSize();
};
#endif

@ -1,50 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>BookmarksWidget</class>
<widget class="QWidget" name="BookmarksWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>323</width>
<height>450</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>1</number>
</property>
<property name="topMargin">
<number>1</number>
</property>
<property name="rightMargin">
<number>1</number>
</property>
<property name="bottomMargin">
<number>1</number>
</property>
<property name="spacing">
<number>1</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Filter:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="filterEdit"/>
</item>
<item row="1" column="0" colspan="2">
<widget class="QTreeView" name="treeView">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

@ -1,114 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FontDialog</class>
<widget class="QDialog" name="FontDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>296</width>
<height>187</height>
</rect>
</property>
<property name="windowTitle">
<string>Select Terminal Font</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="3" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="1" column="0">
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Font:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QFontComboBox" name="fontComboBox"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Size:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="sizeSpinBox">
<property name="minimum">
<number>6</number>
</property>
<property name="value">
<number>10</number>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Preview</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="previewLabel"/>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Select Terminal Font</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>FontDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>FontDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

@ -1,893 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PropertiesDialog</class>
<widget class="QDialog" name="PropertiesDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>952</width>
<height>947</height>
</rect>
</property>
<property name="windowTitle">
<string>Terminal settings</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="2" column="0" colspan="3">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QListWidget" name="listWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>180</width>
<height>16777215</height>
</size>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<item>
<property name="text">
<string>Appearance</string>
</property>
</item>
<item>
<property name="text">
<string>Behavior</string>
</property>
</item>
<item>
<property name="text">
<string>Shortcuts</string>
</property>
</item>
<item>
<property name="text">
<string>Dropdown</string>
</property>
</item>
<item>
<property name="text">
<string>Bookmarks</string>
</property>
</item>
</widget>
</item>
<item row="0" column="2">
<widget class="QStackedWidget" name="stackedWidget">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="appearancePage">
<layout class="QGridLayout" name="gridLayout_3">
<item row="8" column="0">
<widget class="QCheckBox" name="hideTabBarCheckBox">
<property name="text">
<string>Hide tab bar with only one tab</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="colorSchemaCombo"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Color scheme</string>
</property>
<property name="buddy">
<cstring>colorSchemaCombo</cstring>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Scrollbar position</string>
</property>
<property name="buddy">
<cstring>scrollBarPos_comboBox</cstring>
</property>
</widget>
</item>
<item row="19" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Start with preset:</string>
</property>
<property name="buddy">
<cstring>terminalPresetComboBox</cstring>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="scrollBarPos_comboBox"/>
</item>
<item row="5" column="1">
<widget class="QComboBox" name="tabsPos_comboBox"/>
</item>
<item row="10" column="0">
<widget class="QCheckBox" name="highlightCurrentCheckBox">
<property name="text">
<string>Show a border around the current terminal</string>
</property>
</widget>
</item>
<item row="17" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Terminal transparency</string>
</property>
<property name="buddy">
<cstring>termTransparencyBox</cstring>
</property>
</widget>
</item>
<item row="16" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Application transparency</string>
</property>
<property name="buddy">
<cstring>appTransparencyBox</cstring>
</property>
</widget>
</item>
<item row="19" column="1">
<widget class="QComboBox" name="terminalPresetComboBox">
<item>
<property name="text">
<string>None (single terminal)</string>
</property>
</item>
<item>
<property name="text">
<string>2 terminals horizontally</string>
</property>
</item>
<item>
<property name="text">
<string>2 terminals vertically</string>
</property>
</item>
<item>
<property name="text">
<string>4 terminals</string>
</property>
</item>
</widget>
</item>
<item row="16" column="1">
<widget class="QSpinBox" name="appTransparencyBox">
<property name="suffix">
<string> %</string>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>99</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item row="0" column="0" rowspan="2" colspan="2">
<widget class="QWidget" name="fontWidget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="fontLabel">
<property name="text">
<string>Font</string>
</property>
<property name="buddy">
<cstring>changeFontButton</cstring>
</property>
</widget>
</item>
<item>
<spacer name="fontSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="fontSampleLabel">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text">
<string/>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="changeFontButton">
<property name="text">
<string>&amp;Change...</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="styleComboBox"/>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Tabs position</string>
</property>
<property name="buddy">
<cstring>tabsPos_comboBox</cstring>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QComboBox" name="keybCursorShape_comboBox"/>
</item>
<item row="17" column="1">
<widget class="QSpinBox" name="termTransparencyBox">
<property name="suffix">
<string> %</string>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Widget style</string>
</property>
<property name="buddy">
<cstring>styleComboBox</cstring>
</property>
</widget>
</item>
<item row="20" column="0" colspan="2">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="7" column="0">
<widget class="QCheckBox" name="showMenuCheckBox">
<property name="text">
<string>Show the menu bar</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Keyboard cursor shape</string>
</property>
<property name="buddy">
<cstring>keybCursorShape_comboBox</cstring>
</property>
</widget>
</item>
<item row="12" column="0" colspan="2">
<widget class="QCheckBox" name="changeWindowTitleCheckBox">
<property name="text">
<string>Change window title based on current terminal</string>
</property>
</widget>
</item>
<item row="13" column="0" colspan="2">
<widget class="QCheckBox" name="changeWindowIconCheckBox">
<property name="text">
<string>Change window icon based on current terminal</string>
</property>
</widget>
</item>
<item row="15" column="0" colspan="2">
<widget class="QCheckBox" name="enabledBidiSupportCheckBox">
<property name="text">
<string>Enable bi-directional text support</string>
</property>
</widget>
</item>
<item row="18" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Background image:</string>
</property>
</widget>
</item>
<item row="18" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLineEdit" name="backgroundImageLineEdit"/>
</item>
<item>
<widget class="QPushButton" name="chooseBackgroundImageButton">
<property name="text">
<string>Select</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="14" column="0">
<widget class="QCheckBox" name="showTerminalSizeHintCheckBox">
<property name="text">
<string>Show terminal size on resize</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QCheckBox" name="limitTabWidthCheckBox">
<property name="text">
<string>Limit tab width:</string>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QSpinBox" name="limitTabWidthSpinBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="suffix">
<string>px</string>
</property>
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QCheckBox" name="closeTabButtonCheckBox">
<property name="text">
<string>Show close button on each tab</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="behaviorPage">
<layout class="QGridLayout" name="gridLayout_5">
<item row="2" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>57</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Emulation</string>
</property>
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="0">
<widget class="QComboBox" name="emulationComboBox"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Which behavior to emulate. Note that this does not have to match your operating system.&lt;/p&gt;&lt;p&gt;The &lt;span style=&quot; font-weight:600;&quot;&gt;default&lt;/span&gt; emulation is a fallback with a minimal featureset.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Behavior</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Action after paste</string>
</property>
<property name="buddy">
<cstring>motionAfterPasting_comboBox</cstring>
</property>
</widget>
</item>
<item row="3" column="0" colspan="3">
<widget class="QCheckBox" name="confirmMultilinePasteCheckBox">
<property name="text">
<string>Confirm multiline paste</string>
</property>
</widget>
</item>
<item row="4" column="0" colspan="3">
<widget class="QCheckBox" name="trimPastedTrailingNewlinesCheckBox">
<property name="text">
<string>Trim trailing newlines in pasted text</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QSpinBox" name="historyLimitedTo">
<property name="minimum">
<number>100</number>
</property>
<property name="maximum">
<number>1000000</number>
</property>
<property name="value">
<number>1000</number>
</property>
</widget>
</item>
<item row="10" column="1">
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>150</width>
<height>139</height>
</size>
</property>
</spacer>
</item>
<item row="8" column="0" colspan="3">
<widget class="QCheckBox" name="useCwdCheckBox">
<property name="text">
<string>Open new terminals in current working directory</string>
</property>
</widget>
</item>
<item row="7" column="0" colspan="3">
<widget class="QCheckBox" name="saveSizeOnExitCheckBox">
<property name="text">
<string>Save Size when closing</string>
</property>
</widget>
</item>
<item row="6" column="0" colspan="3">
<widget class="QCheckBox" name="savePosOnExitCheckBox">
<property name="text">
<string>Save Position when closing</string>
</property>
</widget>
</item>
<item row="5" column="0" colspan="3">
<widget class="QCheckBox" name="askOnExitCheckBox">
<property name="text">
<string>Ask for confirmation when closing</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QComboBox" name="motionAfterPasting_comboBox"/>
</item>
<item row="1" column="0" colspan="3">
<widget class="QRadioButton" name="historyUnlimited">
<property name="text">
<string>Unlimited history</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QRadioButton" name="historyLimited">
<property name="text">
<string>History size (in lines)</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="label_14">
<property name="text">
<string>Default $TERM</string>
</property>
</widget>
</item>
<item row="9" column="2">
<widget class="QComboBox" name="termComboBox">
<property name="editable">
<bool>true</bool>
</property>
<property name="currentIndex">
<number>1</number>
</property>
<item>
<property name="text">
<string>xterm</string>
</property>
</item>
<item>
<property name="text">
<string>xterm-256color</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="shortcutsPage">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTableWidget" name="shortcutsWidget">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<attribute name="horizontalHeaderDefaultSectionSize">
<number>105</number>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string>Shortcut</string>
</property>
</column>
<column>
<property name="text">
<string>Key</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="dropdownPage">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QCheckBox" name="dropShowOnStartCheckBox">
<property name="text">
<string>Show on start</string>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Size</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="dropHeightLabel">
<property name="text">
<string>Height</string>
</property>
<property name="buddy">
<cstring>dropHeightSpinBox</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="dropHeightSpinBox">
<property name="suffix">
<string>%</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="dropWidthLabel">
<property name="text">
<string>Width</string>
</property>
<property name="buddy">
<cstring>dropWidthSpinBox</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="dropWidthSpinBox">
<property name="suffix">
<string>%</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="dropShortCutLabel">
<property name="text">
<string>Shortcut:</string>
</property>
<property name="buddy">
<cstring>dropShortCutEdit</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="dropShortCutEdit"/>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_5">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>78</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="bookmarksPage">
<layout class="QGridLayout" name="gridLayout_9">
<item row="3" column="0">
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>Edit bookmark file contents</string>
</property>
<layout class="QGridLayout" name="gridLayout_10">
<item row="0" column="0">
<widget class="QPlainTextEdit" name="bookmarkPlainEdit">
<property name="font">
<font>
<family>Bera Sans Mono [bitstream]</family>
<pointsize>11</pointsize>
</font>
</property>
<property name="lineWrapMode">
<enum>QPlainTextEdit::NoWrap</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="useBookmarksCheckBox">
<property name="text">
<string>Enable bookmarks</string>
</property>
</widget>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_10">
<property name="text">
<string>Bookmark file</string>
</property>
<property name="buddy">
<cstring>bookmarksLineEdit</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="bookmarksLineEdit"/>
</item>
<item>
<widget class="QPushButton" name="bookmarksButton">
<property name="text">
<string>Find...</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>You can specify your own bookmarks file location. It allows easy bookmark sharing with tools like OwnCloud or Dropbox.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>listWidget</tabstop>
<tabstop>changeFontButton</tabstop>
<tabstop>colorSchemaCombo</tabstop>
<tabstop>styleComboBox</tabstop>
<tabstop>scrollBarPos_comboBox</tabstop>
<tabstop>tabsPos_comboBox</tabstop>
<tabstop>keybCursorShape_comboBox</tabstop>
<tabstop>showMenuCheckBox</tabstop>
<tabstop>hideTabBarCheckBox</tabstop>
<tabstop>highlightCurrentCheckBox</tabstop>
<tabstop>changeWindowTitleCheckBox</tabstop>
<tabstop>changeWindowIconCheckBox</tabstop>
<tabstop>enabledBidiSupportCheckBox</tabstop>
<tabstop>appTransparencyBox</tabstop>
<tabstop>termTransparencyBox</tabstop>
<tabstop>backgroundImageLineEdit</tabstop>
<tabstop>chooseBackgroundImageButton</tabstop>
<tabstop>terminalPresetComboBox</tabstop>
<tabstop>historyLimited</tabstop>
<tabstop>historyLimitedTo</tabstop>
<tabstop>historyUnlimited</tabstop>
<tabstop>motionAfterPasting_comboBox</tabstop>
<tabstop>askOnExitCheckBox</tabstop>
<tabstop>savePosOnExitCheckBox</tabstop>
<tabstop>saveSizeOnExitCheckBox</tabstop>
<tabstop>useCwdCheckBox</tabstop>
<tabstop>emulationComboBox</tabstop>
<tabstop>shortcutsWidget</tabstop>
<tabstop>dropShowOnStartCheckBox</tabstop>
<tabstop>dropHeightSpinBox</tabstop>
<tabstop>dropWidthSpinBox</tabstop>
<tabstop>dropShortCutEdit</tabstop>
<tabstop>useBookmarksCheckBox</tabstop>
<tabstop>bookmarksLineEdit</tabstop>
<tabstop>bookmarksButton</tabstop>
<tabstop>bookmarkPlainEdit</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>PropertiesDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>224</x>
<y>227</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>248</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>PropertiesDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>292</x>
<y>233</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>248</y>
</hint>
</hints>
</connection>
<connection>
<sender>listWidget</sender>
<signal>currentRowChanged(int)</signal>
<receiver>stackedWidget</receiver>
<slot>setCurrentIndex(int)</slot>
<hints>
<hint type="sourcelabel">
<x>96</x>
<y>70</y>
</hint>
<hint type="destinationlabel">
<x>147</x>
<y>24</y>
</hint>
</hints>
</connection>
<connection>
<sender>limitTabWidthCheckBox</sender>
<signal>toggled(bool)</signal>
<receiver>limitTabWidthSpinBox</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>350</x>
<y>275</y>
</hint>
<hint type="destinationlabel">
<x>618</x>
<y>275</y>
</hint>
</hints>
</connection>
</connections>
</ui>

@ -1,119 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>mainWindow</class>
<widget class="QMainWindow" name="mainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>600</width>
<height>420</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="TabWidget" name="consoleTabulator">
<property name="tabPosition">
<enum>QTabWidget::South</enum>
</property>
<property name="tabShape">
<enum>QTabWidget::Rounded</enum>
</property>
<property name="currentIndex">
<number>-1</number>
</property>
<property name="elideMode">
<enum>Qt::ElideNone</enum>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="m_menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>600</width>
<height>26</height>
</rect>
</property>
<widget class="QMenu" name="menu_File">
<property name="title">
<string>&amp;File</string>
</property>
<property name="Title" stdset="0">
<string/>
</property>
</widget>
<widget class="QMenu" name="menu_Actions">
<property name="title">
<string>&amp;Actions</string>
</property>
</widget>
<widget class="QMenu" name="menu_Help">
<property name="title">
<string>&amp;Help</string>
</property>
<addaction name="actAbout"/>
<addaction name="actAboutQt"/>
</widget>
<widget class="QMenu" name="menu_Window">
<property name="title">
<string>&amp;View</string>
</property>
</widget>
<widget class="QMenu" name="menu_Edit">
<property name="title">
<string>&amp;Edit</string>
</property>
</widget>
<addaction name="menu_File"/>
<addaction name="menu_Actions"/>
<addaction name="menu_Edit"/>
<addaction name="menu_Window"/>
<addaction name="menu_Help"/>
</widget>
<action name="actAbout">
<property name="icon">
<iconset theme="help-about">
<normaloff/>
</iconset>
</property>
<property name="text">
<string>&amp;About...</string>
</property>
</action>
<action name="actAboutQt">
<property name="text">
<string>About &amp;Qt...</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
<class>TabWidget</class>
<extends>QTabWidget</extends>
<header>tabwidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

@ -1,16 +0,0 @@
<RCC>
<qresource prefix="/icons/QTerminal">
<file alias="index.theme">icons/index.theme</file>
<file alias="64x64/utilities-terminal">icons/qterminal.png</file>
<file alias="32x32/list-add.png">icons/list-add.png</file>
<file alias="32x32/list-remove.png">icons/list-remove.png</file>
<file alias="32x32/edit-copy.png">icons/edit-copy.png</file>
<file alias="32x32/edit-paste.png">icons/edit-paste.png</file>
<file alias="32x32/document-close.png">icons/document-close.png</file>
<file alias="32x32/application-exit.png">icons/application-exit.png</file>
<file alias="16x16/object-locked.png">icons/locked.png</file>
<file alias="16x16/object-unlocked.png">icons/notlocked.png</file>
<file alias="22x22/zoom-in.png">icons/zoom-in.png</file>
<file alias="22x22/zoom-out.png">icons/zoom-out.png</file>
</qresource>
</RCC>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 860 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 937 B

@ -1,31 +0,0 @@
[Icon Theme]
Name=QTerminal
Comment=Default Icons used in QTerminal
Inherits=default
Directories=16x16,22x22,24x24,32x32,scalable
[16x16]
Size=16
Type=Fixed
[22x22]
Size=22
Type=Fixed
[24x24]
Size=24
Type=Fixed
[32x32]
Size=32
Type=Fixed
[64x64]
Size=64
Type=Fixed
[scalable]
Size=48
Type=Scalable
MinSize=32
MaxSize=256

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 561 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 541 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

@ -1,60 +0,0 @@
#
# This is evil! I don't know why it works this way.
# But it works.
#
# First - collect all Qt and App plugins. Then call that bloody
# cmake FIXUP_BUNDLE macro which copis all files into MacOS directory.
# So it's moved back to plugins tree where its expected by a) Qt b) application
#
# I hate it.
#
# Dunno what id this var for...
SET(DIRS @QT_LIBRARY_DIRS@;@QT_PLUGINS_DIR@;@CMAKE_INSTALL_PREFIX@/Contents/plugins/)
# qt_menu.nib is mandatory for mac
if (@QT_USE_FRAMEWORKS@)
file(COPY @QT_LIBRARY_DIR@/QtGui.framework/Resources/qt_menu.nib
DESTINATION @CMAKE_INSTALL_PREFIX@/@EXE_NAME@.app/Contents/Resources)
else ()
file(COPY @QT_LIBRARY_DIR@/Resources/qt_menu.nib
DESTINATION @CMAKE_INSTALL_PREFIX@/@EXE_NAME@.app/Contents/Resources)
endif ()
# the qt.conf is mandatory too
file(WRITE @CMAKE_INSTALL_PREFIX@/@EXE_NAME@.app/Contents/Resources/qt.conf "[Paths]
Plugins = plugins")
# copy all (required) Qt plugs into bundle
message(STATUS "Searching for Qt plugs in: @QT_PLUGINS_DIR@/*@CMAKE_SHARED_LIBRARY_SUFFIX@")
file(COPY @QT_PLUGINS_DIR@/
DESTINATION @CMAKE_INSTALL_PREFIX@/@EXE_NAME@.app/Contents/plugins/
REGEX "(designer|script|debug|sql|odbc|phonon|svg|mng|tiff|gif|bearer|accessible|)" EXCLUDE)
#REGEX "(.*)" EXCLUDE)
# try to FIXUP_BUNDLE - to change otool -L paths
# currently it creates lots of false warnings when plugins are compiled as dylibs
# warning: cannot resolve item 'libfoobar.dylib'
# etc. Ignore it.
message(STATUS "Searching for plugs in bundle: @CMAKE_INSTALL_PREFIX@/@EXE_NAME@.app/Contents/plugins/*@CMAKE_SHARED_LIBRARY_SUFFIX@")
file(GLOB_RECURSE inplugs
@CMAKE_INSTALL_PREFIX@/@EXE_NAME@.app/Contents/plugins/*@CMAKE_SHARED_LIBRARY_SUFFIX@)
#message(STATUS "Dylibs: ${inplugs}")
#message(STATUS "DIR: ${DIRS}")
include(BundleUtilities)
fixup_bundle(@CMAKE_INSTALL_PREFIX@/@EXE_NAME@.app "${inplugs}" @CMAKE_INSTALL_PREFIX@/Contents/plugins/)#${DIRS} )
# FIXUP_BUNDLE copies it into MacOS dir. But we need it in plugins *tree*,
# not a flat dir.
foreach (item IN LISTS inplugs)
#message(STATUS "IN: ${item}")
get_filename_component(fname ${item} NAME)
message(STATUS "Moving ${fname} back to plugins tree: ${item}")
#message(STATUS " ${fname}")
#message(STATUS " src: @CMAKE_INSTALL_PREFIX@/@EXE_NAME@.app/Contents/MacOS/${fname}")
#message(STATUS " tgt: ${item}")
execute_process(COMMAND mv @CMAKE_INSTALL_PREFIX@/@EXE_NAME@.app/Contents/MacOS/${fname} ${item})
endforeach()

Binary file not shown.

@ -1,318 +0,0 @@
/***************************************************************************
* Copyright (C) 2006 by Vladimir Kuznetsov *
* vovanec@gmail.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include <QApplication>
#include <QtGlobal>
#include <assert.h>
#include <stdio.h>
#include <getopt.h>
#include <stdlib.h>
#ifdef HAVE_QDBUS
#include <QtDBus/QtDBus>
#include <unistd.h>
#include "processadaptor.h"
#endif
#include "mainwindow.h"
#include "qterminalapp.h"
#include "terminalconfig.h"
#define out
const char* const short_options = "vhw:e:dp:";
const struct option long_options[] = {
{"version", 0, NULL, 'v'},
{"help", 0, NULL, 'h'},
{"workdir", 1, NULL, 'w'},
{"execute", 1, NULL, 'e'},
{"drop", 0, NULL, 'd'},
{"profile", 1, NULL, 'p'},
{NULL, 0, NULL, 0}
};
QTerminalApp * QTerminalApp::m_instance = NULL;
void print_usage_and_exit(int code)
{
printf("QTerminal %s\n", STR_VERSION);
puts("Usage: qterminal [OPTION]...\n");
puts(" -d, --drop Start in \"dropdown mode\" (like Yakuake or Tilda)");
puts(" -e, --execute <command> Execute command instead of shell");
puts(" -h, --help Print this help");
puts(" -p, --profile Load qterminal with specific options");
puts(" -v, --version Prints application version and exits");
puts(" -w, --workdir <dir> Start session with specified work directory");
puts("\nHomepage: <https://github.com/lxqt/qterminal>");
puts("Report bugs to <https://github.com/lxqt/qterminal/issues>");
exit(code);
}
void print_version_and_exit(int code=0)
{
printf("%s\n", STR_VERSION);
exit(code);
}
void parse_args(int argc, char* argv[], QString& workdir, QString & shell_command, out bool& dropMode)
{
int next_option;
dropMode = false;
do{
next_option = getopt_long(argc, argv, short_options, long_options, NULL);
switch(next_option)
{
case 'h':
print_usage_and_exit(0);
case 'w':
workdir = QString(optarg);
break;
case 'e':
shell_command = QString(optarg);
// #15 "Raw" -e params
// Passing "raw" params (like konsole -e mcedit /tmp/tmp.txt") is more preferable - then I can call QString("qterminal -e ") + cmd_line in other programs
while (optind < argc)
{
//printf("arg: %d - %s\n", optind, argv[optind]);
shell_command += ' ' + QString(argv[optind++]);
}
break;
case 'd':
dropMode = true;
break;
case 'p':
Properties::Instance(QString(optarg));
break;
case '?':
print_usage_and_exit(1);
case 'v':
print_version_and_exit();
}
}
while(next_option != -1);
}
int main(int argc, char *argv[])
{
QApplication::setApplicationName("qterminal");
QApplication::setApplicationVersion(STR_VERSION);
QApplication::setOrganizationDomain("qterminal.org");
#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
QApplication::setDesktopFileName(QLatin1String("qterminal.desktop"));
#endif
// Warning: do not change settings format. It can screw bookmarks later.
QSettings::setDefaultFormat(QSettings::IniFormat);
QTerminalApp *app = QTerminalApp::Instance(argc, argv);
#ifdef HAVE_QDBUS
app->registerOnDbus();
#endif
QString workdir, shell_command;
bool dropMode;
parse_args(argc, argv, workdir, shell_command, dropMode);
Properties::Instance()->migrate_settings();
Properties::Instance()->loadSettings();
qputenv("TERM", Properties::Instance()->term.toLatin1());
if (workdir.isEmpty())
workdir = QDir::currentPath();
app->setWorkingDirectory(workdir);
const QSettings settings;
const QFileInfo customStyle = QFileInfo(
QFileInfo(settings.fileName()).canonicalPath() +
"/style.qss"
);
if (customStyle.isFile() && customStyle.isReadable())
{
QFile style(customStyle.canonicalFilePath());
style.open(QFile::ReadOnly);
QString styleString = QLatin1String(style.readAll());
app->setStyleSheet(styleString);
}
// icons
/* setup our custom icon theme if there is no system theme (OS X, Windows) */
QCoreApplication::instance()->setAttribute(Qt::AA_UseHighDpiPixmaps); //Fix for High-DPI systems
if (QIcon::themeName().isEmpty())
QIcon::setThemeName("QTerminal");
// translations
QString fname = QString("qterminal_%1.qm").arg(QLocale::system().name().left(5));
QTranslator translator;
#ifdef TRANSLATIONS_DIR
qDebug() << "TRANSLATIONS_DIR: Loading translation file" << fname << "from dir" << TRANSLATIONS_DIR;
qDebug() << "load success:" << translator.load(fname, TRANSLATIONS_DIR, "_");
#endif
#ifdef APPLE_BUNDLE
qDebug() << "APPLE_BUNDLE: Loading translator file" << fname << "from dir" << QApplication::applicationDirPath()+"../translations";
qDebug() << "load success:" << translator.load(fname, QApplication::applicationDirPath()+"../translations", "_");
#endif
app->installTranslator(&translator);
TerminalConfig initConfig = TerminalConfig(workdir, shell_command);
app->newWindow(dropMode, initConfig);
int ret = app->exec();
delete Properties::Instance();
app->cleanup();
return ret;
}
MainWindow *QTerminalApp::newWindow(bool dropMode, TerminalConfig &cfg)
{
MainWindow *window = NULL;
if (dropMode)
{
QWidget *hiddenPreviewParent = new QWidget(0, Qt::Tool);
window = new MainWindow(cfg, dropMode, hiddenPreviewParent);
if (Properties::Instance()->dropShowOnStart)
window->show();
}
else
{
window = new MainWindow(cfg, dropMode);
window->show();
}
return window;
}
QTerminalApp *QTerminalApp::Instance()
{
assert(m_instance != NULL);
return m_instance;
}
QTerminalApp *QTerminalApp::Instance(int &argc, char **argv)
{
assert(m_instance == NULL);
m_instance = new QTerminalApp(argc, argv);
return m_instance;
}
QTerminalApp::QTerminalApp(int &argc, char **argv)
:QApplication(argc, argv)
{
}
QString &QTerminalApp::getWorkingDirectory()
{
return m_workDir;
}
void QTerminalApp::setWorkingDirectory(const QString &wd)
{
m_workDir = wd;
}
void QTerminalApp::cleanup() {
delete m_instance;
m_instance = NULL;
}
void QTerminalApp::addWindow(MainWindow *window)
{
m_windowList.append(window);
}
void QTerminalApp::removeWindow(MainWindow *window)
{
m_windowList.removeOne(window);
}
QList<MainWindow *> QTerminalApp::getWindowList()
{
return m_windowList;
}
#ifdef HAVE_QDBUS
void QTerminalApp::registerOnDbus()
{
if (!QDBusConnection::sessionBus().isConnected())
{
fprintf(stderr, "Cannot connect to the D-Bus session bus.\n"
"To start it, run:\n"
"\teval `dbus-launch --auto-syntax`\n");
return;
}
QString serviceName = QStringLiteral("org.lxqt.QTerminal-%1").arg(getpid());
if (!QDBusConnection::sessionBus().registerService(serviceName))
{
fprintf(stderr, "%s\n", qPrintable(QDBusConnection::sessionBus().lastError().message()));
return;
}
new ProcessAdaptor(this);
QDBusConnection::sessionBus().registerObject("/", this);
}
QList<QDBusObjectPath> QTerminalApp::getWindows()
{
QList<QDBusObjectPath> windows;
for (MainWindow *wnd : qAsConst(m_windowList))
{
windows.push_back(wnd->getDbusPath());
}
return windows;
}
QDBusObjectPath QTerminalApp::newWindow(const QHash<QString,QVariant> &termArgs)
{
TerminalConfig cfg = TerminalConfig::fromDbus(termArgs);
MainWindow *wnd = newWindow(false, cfg);
assert(wnd != NULL);
return wnd->getDbusPath();
}
QDBusObjectPath QTerminalApp::getActiveWindow()
{
QWidget *aw = activeWindow();
if (aw == NULL)
return QDBusObjectPath("/");
return qobject_cast<MainWindow*>(aw)->getDbusPath();
}
bool QTerminalApp::isDropMode() {
if (m_windowList.count() == 0) {
return false;
}
MainWindow *wnd = m_windowList.at(0);
return wnd->dropMode();
}
bool QTerminalApp::toggleDropdown() {
if (m_windowList.count() == 0) {
return false;
}
MainWindow *wnd = m_windowList.at(0);
if (!wnd->dropMode()) {
return false;
}
wnd->showHide();
return true;
}
#endif

@ -1,809 +0,0 @@
/***************************************************************************
* Copyright (C) 2006 by Vladimir Kuznetsov *
* vovanec@gmail.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include <QDockWidget>
#include <QDesktopWidget>
#include <QToolButton>
#include <QMessageBox>
#include <functional>
#ifdef HAVE_QDBUS
#include <QtDBus/QtDBus>
#include "windowadaptor.h"
#endif
#include "terminalconfig.h"
#include "mainwindow.h"
#include "tabwidget.h"
#include "termwidgetholder.h"
#include "config.h"
#include "properties.h"
#include "propertiesdialog.h"
#include "bookmarkswidget.h"
#include "qterminalapp.h"
#include "dbusaddressable.h"
typedef std::function<bool(MainWindow&)> checkfn;
Q_DECLARE_METATYPE(checkfn)
// TODO/FXIME: probably remove. QSS makes it unusable on mac...
#define QSS_DROP "MainWindow {border: 1px solid rgba(0, 0, 0, 50%);}\n"
MainWindow::MainWindow(TerminalConfig &cfg,
bool dropMode,
QWidget * parent,
Qt::WindowFlags f)
: QMainWindow(parent,f),
DBusAddressable("/windows"),
tabPosition(NULL),
scrollBarPosition(NULL),
keyboardCursorShape(NULL),
tabPosMenu(NULL),
scrollPosMenu(NULL),
keyboardCursorShapeMenu(NULL),
settingOwner(NULL),
presetsMenu(NULL),
m_config(cfg),
m_dropLockButton(0),
m_dropMode(dropMode)
{
#ifdef HAVE_QDBUS
registerAdapter<WindowAdaptor, MainWindow>(this);
#endif
m_removeFinished = false;
QTerminalApp::Instance()->addWindow(this);
// We want terminal translucency...
setAttribute(Qt::WA_TranslucentBackground);
// ... but neither a fully transparent nor a flat menubar
// with styles that have translucency and/or gradient.
setAttribute(Qt::WA_NoSystemBackground, false);
setAttribute(Qt::WA_DeleteOnClose);
setupUi(this);
m_bookmarksDock = new QDockWidget(tr("Bookmarks"), this);
m_bookmarksDock->setObjectName("BookmarksDockWidget");
m_bookmarksDock->setAutoFillBackground(true);
BookmarksWidget *bookmarksWidget = new BookmarksWidget(m_bookmarksDock);
bookmarksWidget->setAutoFillBackground(true);
m_bookmarksDock->setWidget(bookmarksWidget);
addDockWidget(Qt::LeftDockWidgetArea, m_bookmarksDock);
connect(bookmarksWidget, &BookmarksWidget::callCommand,
this, &MainWindow::bookmarksWidget_callCommand);
connect(m_bookmarksDock, &QDockWidget::visibilityChanged,
this, &MainWindow::bookmarksDock_visibilityChanged);
connect(actAbout, &QAction::triggered, this, &MainWindow::actAbout_triggered);
connect(actAboutQt, &QAction::triggered, qApp, &QApplication::aboutQt);
connect(&m_dropShortcut, &QxtGlobalShortcut::activated, this, &MainWindow::showHide);
setContentsMargins(0, 0, 0, 0);
if (m_dropMode) {
this->enableDropMode();
setStyleSheet(QSS_DROP);
}
else {
if (Properties::Instance()->saveSizeOnExit) {
resize(Properties::Instance()->mainWindowSize);
}
if (Properties::Instance()->savePosOnExit) {
move(Properties::Instance()->mainWindowPosition);
}
restoreState(Properties::Instance()->mainWindowState);
}
consoleTabulator->setAutoFillBackground(true);
connect(consoleTabulator, &TabWidget::closeTabNotification, this, &MainWindow::testClose);
consoleTabulator->setTabPosition((QTabWidget::TabPosition)Properties::Instance()->tabsPos);
//consoleTabulator->setShellProgram(command);
// apply props
propertiesChanged();
setupCustomDirs();
connect(consoleTabulator, &TabWidget::currentTitleChanged, this, &MainWindow::onCurrentTitleChanged);
connect(menu_Actions, &QMenu::aboutToShow, this, &MainWindow::updateDisabledActions);
/* The tab should be added after all changes are made to
the main window; otherwise, the initial prompt might
get jumbled because of changes in internal geometry. */
consoleTabulator->addNewTab(m_config);
}
void MainWindow::rebuildActions()
{
// Delete all setting-related QObjects
delete settingOwner;
settingOwner = new QWidget(this);
settingOwner->setGeometry(0,0,0,0);
// Then create them again
setup_FileMenu_Actions();
setup_ActionsMenu_Actions();
setup_ViewMenu_Actions();
}
MainWindow::~MainWindow()
{
QTerminalApp::Instance()->removeWindow(this);
}
void MainWindow::enableDropMode()
{
setWindowFlags(Qt::Dialog | Qt::WindowStaysOnTopHint | Qt::CustomizeWindowHint);
m_dropLockButton = new QToolButton(this);
consoleTabulator->setCornerWidget(m_dropLockButton, Qt::BottomRightCorner);
m_dropLockButton->setCheckable(true);
m_dropLockButton->connect(m_dropLockButton, &QToolButton::clicked, this, &MainWindow::setKeepOpen);
setKeepOpen(Properties::Instance()->dropKeepOpen);
m_dropLockButton->setAutoRaise(true);
setDropShortcut(Properties::Instance()->dropShortCut);
realign();
}
void MainWindow::setDropShortcut(QKeySequence dropShortCut)
{
if (!m_dropMode)
return;
if (m_dropShortcut.shortcut() != dropShortCut)
{
m_dropShortcut.setShortcut(dropShortCut);
qWarning() << tr("Press \"%1\" to see the terminal.").arg(dropShortCut.toString());
}
}
void MainWindow::setup_Action(const char *name, QAction *action, const char *defaultShortcut, const QObject *receiver,
const char *slot, QMenu *menu, const QVariant &data)
{
QSettings settings;
settings.beginGroup("Shortcuts");
QList<QKeySequence> shortcuts;
actions[name] = action;
const auto sequences = settings.value(name, defaultShortcut).toString().split('|');
for (const QString &sequenceString : sequences)
shortcuts.append(QKeySequence::fromString(sequenceString));
actions[name]->setShortcuts(shortcuts);
if (receiver)
{
connect(actions[name], SIGNAL(triggered(bool)), receiver, slot);
addAction(actions[name]);
}
if (menu)
menu->addAction(actions[name]);
if (!data.isNull())
actions[name]->setData(data);
}
void MainWindow::setup_ActionsMenu_Actions()
{
QVariant data;
const checkfn checkTabs = &MainWindow::hasMultipleTabs;
const checkfn checkSubterminals = &MainWindow::hasMultipleSubterminals;
menu_Actions->clear();
setup_Action(CLEAR_TERMINAL, new QAction(QIcon::fromTheme("edit-clear"), tr("&Clear Active Terminal"), settingOwner),
CLEAR_TERMINAL_SHORTCUT, consoleTabulator, SLOT(clearActiveTerminal()), menu_Actions);
menu_Actions->addSeparator();
data.setValue(checkTabs);
setup_Action(TAB_NEXT, new QAction(QIcon::fromTheme("go-next"), tr("&Next Tab"), settingOwner),
TAB_NEXT_SHORTCUT, consoleTabulator, SLOT(switchToRight()), menu_Actions, data);
setup_Action(TAB_PREV, new QAction(QIcon::fromTheme("go-previous"), tr("&Previous Tab"), settingOwner),
TAB_PREV_SHORTCUT, consoleTabulator, SLOT(switchToLeft()), menu_Actions, data);
setup_Action(MOVE_LEFT, new QAction(tr("Move Tab &Left"), settingOwner),
MOVE_LEFT_SHORTCUT, consoleTabulator, SLOT(moveLeft()), menu_Actions, data);
setup_Action(MOVE_RIGHT, new QAction(tr("Move Tab &Right"), settingOwner),
MOVE_RIGHT_SHORTCUT, consoleTabulator, SLOT(moveRight()), menu_Actions, data);
menu_Actions->addSeparator();
setup_Action(SPLIT_HORIZONTAL, new QAction(tr("Split Terminal &Horizontally"), settingOwner),
NULL, consoleTabulator, SLOT(splitHorizontally()), menu_Actions);
setup_Action(SPLIT_VERTICAL, new QAction(tr("Split Terminal &Vertically"), settingOwner),
NULL, consoleTabulator, SLOT(splitVertically()), menu_Actions);
data.setValue(checkSubterminals);
setup_Action(SUB_COLLAPSE, new QAction(tr("&Collapse Subterminal"), settingOwner),
NULL, consoleTabulator, SLOT(splitCollapse()), menu_Actions, data);
setup_Action(SUB_TOP, new QAction(QIcon::fromTheme("go-up"), tr("&Top Subterminal"), settingOwner),
SUB_TOP_SHORTCUT, consoleTabulator, SLOT(switchTopSubterminal()), menu_Actions, data);
setup_Action(SUB_BOTTOM, new QAction(QIcon::fromTheme("go-down"), tr("&Bottom Subterminal"), settingOwner),
SUB_BOTTOM_SHORTCUT, consoleTabulator, SLOT(switchBottomSubterminal()), menu_Actions, data);
setup_Action(SUB_LEFT, new QAction(QIcon::fromTheme("go-previous"), tr("L&eft Subterminal"), settingOwner),
SUB_LEFT_SHORTCUT, consoleTabulator, SLOT(switchLeftSubterminal()), menu_Actions, data);
setup_Action(SUB_RIGHT, new QAction(QIcon::fromTheme("go-next"), tr("R&ight Subterminal"), settingOwner),
SUB_RIGHT_SHORTCUT, consoleTabulator, SLOT(switchRightSubterminal()), menu_Actions, data);
menu_Actions->addSeparator();
// Copy and Paste are only added to the table for the sake of bindings at the moment; there is no Edit menu, only a context menu.
setup_Action(COPY_SELECTION, new QAction(QIcon::fromTheme("edit-copy"), tr("Copy &Selection"), settingOwner),
COPY_SELECTION_SHORTCUT, consoleTabulator, SLOT(copySelection()), menu_Edit);
setup_Action(PASTE_CLIPBOARD, new QAction(QIcon::fromTheme("edit-paste"), tr("Paste Clip&board"), settingOwner),
PASTE_CLIPBOARD_SHORTCUT, consoleTabulator, SLOT(pasteClipboard()), menu_Edit);
setup_Action(PASTE_SELECTION, new QAction(QIcon::fromTheme("edit-paste"), tr("Paste S&election"), settingOwner),
PASTE_SELECTION_SHORTCUT, consoleTabulator, SLOT(pasteSelection()), menu_Edit);
setup_Action(ZOOM_IN, new QAction(QIcon::fromTheme("zoom-in"), tr("Zoom &in"), settingOwner),
ZOOM_IN_SHORTCUT, consoleTabulator, SLOT(zoomIn()), menu_Edit);
setup_Action(ZOOM_OUT, new QAction(QIcon::fromTheme("zoom-out"), tr("Zoom &out"), settingOwner),
ZOOM_OUT_SHORTCUT, consoleTabulator, SLOT(zoomOut()), menu_Edit);
setup_Action(ZOOM_RESET, new QAction(QIcon::fromTheme("zoom-original"), tr("Zoom rese&t"), settingOwner),
ZOOM_RESET_SHORTCUT, consoleTabulator, SLOT(zoomReset()), menu_Edit);
menu_Actions->addSeparator();
setup_Action(FIND, new QAction(QIcon::fromTheme("edit-find"), tr("&Find..."), settingOwner),
FIND_SHORTCUT, this, SLOT(find()), menu_Actions);
#if 0
act = new QAction(this);
act->setSeparator(true);
// TODO/FIXME: unimplemented for now
act = new QAction(tr("&Save Session"), this);
// do not use sequences for this task - it collides with eg. mc shorcuts
// and mainly - it's not used too often
//act->setShortcut(QKeySequence::Save);
connect(act, SIGNAL(triggered()), consoleTabulator, SLOT(saveSession()));
act = new QAction(tr("&Load Session"), this);
// do not use sequences for this task - it collides with eg. mc shorcuts
// and mainly - it's not used too often
//act->setShortcut(QKeySequence::Open);
connect(act, SIGNAL(triggered()), consoleTabulator, SLOT(loadSession()));
#endif
setup_Action(TOGGLE_MENU, new QAction(tr("&Toggle Menu"), settingOwner),
TOGGLE_MENU_SHORTCUT, this, SLOT(toggleMenu()));
// this is correct - add action to main window - not to menu to keep toggle working
// Add global rename current session shortcut
setup_Action(RENAME_SESSION, new QAction(tr("Rename session"), settingOwner),
RENAME_SESSION_SHORTCUT, consoleTabulator, SLOT(renameCurrentSession()));
// this is correct - add action to main window - not to menu
}
void MainWindow::setup_FileMenu_Actions()
{
menu_File->clear();
setup_Action(ADD_TAB, new QAction(QIcon::fromTheme("list-add"), tr("&New Tab"), settingOwner),
ADD_TAB_SHORTCUT, this, SLOT(addNewTab()), menu_File);
if (presetsMenu == NULL) {
presetsMenu = new QMenu(tr("New Tab From &Preset"), this);
presetsMenu->addAction(QIcon(), tr("1 &Terminal"),
this, SLOT(addNewTab()));
presetsMenu->addAction(QIcon(), tr("2 &Horizontal Terminals"),
consoleTabulator, SLOT(preset2Horizontal()));
presetsMenu->addAction(QIcon(), tr("2 &Vertical Terminals"),
consoleTabulator, SLOT(preset2Vertical()));
presetsMenu->addAction(QIcon(), tr("4 Terminal&s"),
consoleTabulator, SLOT(preset4Terminals()));
}
menu_File->addMenu(presetsMenu);
setup_Action(CLOSE_TAB, new QAction(QIcon::fromTheme("list-remove"), tr("&Close Tab"), settingOwner),
CLOSE_TAB_SHORTCUT, consoleTabulator, SLOT(removeCurrentTab()), menu_File);
setup_Action(NEW_WINDOW, new QAction(QIcon::fromTheme("window-new"), tr("&New Window"), settingOwner),
NEW_WINDOW_SHORTCUT, this, SLOT(newTerminalWindow()), menu_File);
menu_File->addSeparator();
setup_Action(PREFERENCES, new QAction(tr("&Preferences..."), settingOwner), "", this, SLOT(actProperties_triggered()), menu_File);
menu_File->addSeparator();
setup_Action(QUIT, new QAction(QIcon::fromTheme("application-exit"), tr("&Quit"), settingOwner), "", this, SLOT(close()), menu_File);
}
void MainWindow::setup_ViewMenu_Actions()
{
menu_Window->clear();
QAction *hideBordersAction = new QAction(tr("&Hide Window Borders"), settingOwner);
hideBordersAction->setCheckable(true);
hideBordersAction->setVisible(!m_dropMode);
setup_Action(HIDE_WINDOW_BORDERS, hideBordersAction,
NULL, this, SLOT(toggleBorderless()), menu_Window);
//Properties::Instance()->actions[HIDE_WINDOW_BORDERS]->setObjectName("toggle_Borderless");
// TODO/FIXME: it's broken somehow. When I call toggleBorderless() here the non-responsive window appear
// actions[HIDE_WINDOW_BORDERS]->setChecked(Properties::Instance()->borderless);
// if (Properties::Instance()->borderless)
// toggleBorderless();
QAction *showTabBarAction = new QAction(tr("&Show Tab Bar"), settingOwner);
//toggleTabbar->setObjectName("toggle_TabBar");
showTabBarAction->setCheckable(true);
showTabBarAction->setChecked(!Properties::Instance()->tabBarless);
setup_Action(SHOW_TAB_BAR, showTabBarAction,
NULL, this, SLOT(toggleTabBar()), menu_Window);
toggleTabBar();
QAction *toggleFullscreen = new QAction(tr("Fullscreen"), settingOwner);
toggleFullscreen->setCheckable(true);
toggleFullscreen->setChecked(false);
setup_Action(FULLSCREEN, toggleFullscreen,
FULLSCREEN_SHORTCUT, this, SLOT(showFullscreen(bool)), menu_Window);
setup_Action(TOGGLE_BOOKMARKS, new QAction(tr("Toggle Bookmarks"), settingOwner),
TOGGLE_BOOKMARKS_SHORTCUT, NULL, NULL, menu_Window);
menu_Window->addSeparator();
/* tabs position */
if (tabPosition == NULL) {
tabPosition = new QActionGroup(this);
QAction *tabBottom = new QAction(tr("&Bottom"), this);
QAction *tabTop = new QAction(tr("&Top"), this);
QAction *tabRight = new QAction(tr("&Right"), this);
QAction *tabLeft = new QAction(tr("&Left"), this);
tabPosition->addAction(tabTop);
tabPosition->addAction(tabBottom);
tabPosition->addAction(tabLeft);
tabPosition->addAction(tabRight);
for(int i = 0; i < tabPosition->actions().size(); ++i)
tabPosition->actions().at(i)->setCheckable(true);
}
if( tabPosition->actions().count() > Properties::Instance()->tabsPos )
tabPosition->actions().at(Properties::Instance()->tabsPos)->setChecked(true);
connect(tabPosition, &QActionGroup::triggered,
consoleTabulator, &TabWidget::changeTabPosition);
if (tabPosMenu == NULL) {
tabPosMenu = new QMenu(tr("&Tabs Layout"), menu_Window);
tabPosMenu->setObjectName("tabPosMenu");
for(int i=0; i < tabPosition->actions().size(); ++i) {
tabPosMenu->addAction(tabPosition->actions().at(i));
}
connect(menu_Window, &QMenu::hovered,
this, &MainWindow::updateActionGroup);
}
menu_Window->addMenu(tabPosMenu);
/* */
/* Scrollbar */
if (scrollBarPosition == NULL) {
scrollBarPosition = new QActionGroup(this);
QAction *scrollNone = new QAction(tr("&None"), this);
QAction *scrollRight = new QAction(tr("&Right"), this);
QAction *scrollLeft = new QAction(tr("&Left"), this);
/* order of insertion is dep. on QTermWidget::ScrollBarPosition enum */
scrollBarPosition->addAction(scrollNone);
scrollBarPosition->addAction(scrollLeft);
scrollBarPosition->addAction(scrollRight);
for(int i = 0; i < scrollBarPosition->actions().size(); ++i)
scrollBarPosition->actions().at(i)->setCheckable(true);
if( Properties::Instance()->scrollBarPos < scrollBarPosition->actions().size() )
scrollBarPosition->actions().at(Properties::Instance()->scrollBarPos)->setChecked(true);
connect(scrollBarPosition, &QActionGroup::triggered,
consoleTabulator, &TabWidget::changeScrollPosition);
}
if (scrollPosMenu == NULL) {
scrollPosMenu = new QMenu(tr("S&crollbar Layout"), menu_Window);
scrollPosMenu->setObjectName("scrollPosMenu");
for(int i=0; i < scrollBarPosition->actions().size(); ++i) {
scrollPosMenu->addAction(scrollBarPosition->actions().at(i));
}
}
menu_Window->addMenu(scrollPosMenu);
/* Keyboard cursor shape */
if (keyboardCursorShape == NULL) {
keyboardCursorShape = new QActionGroup(this);
QAction *block = new QAction(tr("&BlockCursor"), this);
QAction *underline = new QAction(tr("&UnderlineCursor"), this);
QAction *ibeam = new QAction(tr("&IBeamCursor"), this);
/* order of insertion is dep. on QTermWidget::KeyboardCursorShape enum */
keyboardCursorShape->addAction(block);
keyboardCursorShape->addAction(underline);
keyboardCursorShape->addAction(ibeam);
for(int i = 0; i < keyboardCursorShape->actions().size(); ++i)
keyboardCursorShape->actions().at(i)->setCheckable(true);
if( Properties::Instance()->keyboardCursorShape < keyboardCursorShape->actions().size() )
keyboardCursorShape->actions().at(Properties::Instance()->keyboardCursorShape)->setChecked(true);
connect(keyboardCursorShape, &QActionGroup::triggered,
consoleTabulator, &TabWidget::changeKeyboardCursorShape);
}
if (keyboardCursorShapeMenu == NULL) {
keyboardCursorShapeMenu = new QMenu(tr("&Keyboard Cursor Shape"), menu_Window);
keyboardCursorShapeMenu->setObjectName("keyboardCursorShapeMenu");
for(int i=0; i < keyboardCursorShape->actions().size(); ++i) {
keyboardCursorShapeMenu->addAction(keyboardCursorShape->actions().at(i));
}
}
menu_Window->addMenu(keyboardCursorShapeMenu);
}
void MainWindow::setupCustomDirs()
{
const QSettings settings;
const QString dir = QFileInfo(settings.fileName()).canonicalPath() + "/color-schemes/";
TermWidgetImpl::addCustomColorSchemeDir(dir);
}
void MainWindow::on_consoleTabulator_currentChanged(int)
{
}
void MainWindow::toggleTabBar()
{
Properties::Instance()->tabBarless
= !actions[SHOW_TAB_BAR]->isChecked();
consoleTabulator->showHideTabBar();
}
void MainWindow::toggleBorderless()
{
setWindowFlags(windowFlags() ^ Qt::FramelessWindowHint);
show();
setWindowState(Qt::WindowActive); /* don't loose focus on the window */
Properties::Instance()->borderless
= actions[HIDE_WINDOW_BORDERS]->isChecked(); realign();
}
void MainWindow::toggleMenu()
{
m_menuBar->setVisible(!m_menuBar->isVisible());
Properties::Instance()->menuVisible = m_menuBar->isVisible();
}
void MainWindow::showFullscreen(bool fullscreen)
{
if(fullscreen)
setWindowState(windowState() | Qt::WindowFullScreen);
else
setWindowState(windowState() & ~Qt::WindowFullScreen);
}
void MainWindow::testClose(bool removeFinished)
{
m_removeFinished = removeFinished;
close();
}
void MainWindow::toggleBookmarks()
{
m_bookmarksDock->toggleViewAction()->trigger();
}
void MainWindow::closeEvent(QCloseEvent *ev)
{
if (!Properties::Instance()->askOnExit
|| !consoleTabulator->count())
{
// #80 - do not save state and geometry in drop mode
if (!m_dropMode) {
if (Properties::Instance()->savePosOnExit) {
Properties::Instance()->mainWindowPosition = pos();
}
if (Properties::Instance()->saveSizeOnExit) {
Properties::Instance()->mainWindowSize = size();
}
Properties::Instance()->mainWindowState = saveState();
}
Properties::Instance()->saveSettings();
for (int i = consoleTabulator->count(); i > 0; --i) {
consoleTabulator->removeTab(i - 1);
}
ev->accept();
return;
}
// ask user for cancel only when there is at least one terminal active in this window
QDialog * dia = new QDialog(this);
dia->setObjectName("exitDialog");
dia->setWindowTitle(tr("Exit QTerminal"));
QCheckBox * dontAskCheck = new QCheckBox(tr("Do not ask again"), dia);
QDialogButtonBox * buttonBox = new QDialogButtonBox(QDialogButtonBox::Yes | QDialogButtonBox::No, Qt::Horizontal, dia);
buttonBox->button(QDialogButtonBox::Yes)->setDefault(true);
connect(buttonBox, &QDialogButtonBox::accepted, dia, &QDialog::accept);
connect(buttonBox, &QDialogButtonBox::rejected, dia, &QDialog::reject);
QVBoxLayout * lay = new QVBoxLayout();
lay->addWidget(new QLabel(tr("Are you sure you want to exit?")));
lay->addWidget(dontAskCheck);
lay->addWidget(buttonBox);
dia->setLayout(lay);
if (dia->exec() == QDialog::Accepted) {
Properties::Instance()->mainWindowPosition = pos();
Properties::Instance()->mainWindowSize = size();
Properties::Instance()->mainWindowState = saveState();
Properties::Instance()->askOnExit = !dontAskCheck->isChecked();
Properties::Instance()->saveSettings();
for (int i = consoleTabulator->count(); i > 0; --i) {
consoleTabulator->removeTab(i - 1);
}
ev->accept();
} else {
if(m_removeFinished) {
QWidget *w = consoleTabulator->widget(consoleTabulator->count()-1);
consoleTabulator->removeTab(consoleTabulator->count()-1);
delete w; // delete the widget because the window isn't closed
m_removeFinished = false;
}
ev->ignore();
}
dia->deleteLater();
}
void MainWindow::actAbout_triggered()
{
QMessageBox::about(this, QString("QTerminal ") + STR_VERSION, tr("A lightweight multiplatform terminal emulator"));
}
void MainWindow::actProperties_triggered()
{
PropertiesDialog *p = new PropertiesDialog(this);
connect(p, &PropertiesDialog::propertiesChanged, this, &MainWindow::propertiesChanged);
p->exec();
}
void MainWindow::propertiesChanged()
{
rebuildActions();
QApplication::setStyle(Properties::Instance()->guiStyle);
setWindowOpacity(1.0 - Properties::Instance()->appTransparency/100.0);
consoleTabulator->setTabPosition((QTabWidget::TabPosition)Properties::Instance()->tabsPos);
consoleTabulator->propertiesChanged();
setDropShortcut(Properties::Instance()->dropShortCut);
m_menuBar->setVisible(Properties::Instance()->menuVisible);
m_bookmarksDock->setVisible(Properties::Instance()->useBookmarks
&& Properties::Instance()->bookmarksVisible);
actions[TOGGLE_BOOKMARKS]->setVisible(Properties::Instance()->useBookmarks);
if (Properties::Instance()->useBookmarks)
{
qobject_cast<BookmarksWidget*>(m_bookmarksDock->widget())->setup();
}
onCurrentTitleChanged(consoleTabulator->currentIndex());
realign();
}
void MainWindow::realign()
{
if (m_dropMode)
{
QRect desktop = QApplication::desktop()->availableGeometry(this);
QRect geometry = QRect(0, 0,
desktop.width() * Properties::Instance()->dropWidht / 100,
desktop.height() * Properties::Instance()->dropHeight / 100
);
geometry.moveCenter(desktop.center());
// do not use 0 here - we need to calculate with potential panel on top
geometry.setTop(desktop.top());
if (geometry != this->geometry()) {
setGeometry(geometry);
}
}
}
void MainWindow::updateActionGroup(QAction *a)
{
if (a->parent()->objectName() == tabPosMenu->objectName()) {
tabPosition->actions().at(Properties::Instance()->tabsPos)->setChecked(true);
}
}
void MainWindow::showHide()
{
if (isVisible())
hide();
else
{
realign();
show();
activateWindow();
}
}
void MainWindow::setKeepOpen(bool value)
{
Properties::Instance()->dropKeepOpen = value;
if (!m_dropLockButton)
return;
if (value)
m_dropLockButton->setIcon(QIcon::fromTheme("object-locked"));
else
m_dropLockButton->setIcon(QIcon::fromTheme("object-unlocked"));
m_dropLockButton->setChecked(value);
}
void MainWindow::find()
{
// A bit ugly perhaps with 4 levels of indirection...
consoleTabulator->terminalHolder()->currentTerminal()->impl()->toggleShowSearchBar();
}
bool MainWindow::event(QEvent *event)
{
if (event->type() == QEvent::WindowDeactivate)
{
if (m_dropMode &&
!Properties::Instance()->dropKeepOpen &&
qApp->activeWindow() == 0
)
hide();
}
return QMainWindow::event(event);
}
void MainWindow::newTerminalWindow()
{
TerminalConfig cfg;
TermWidgetHolder *ch = consoleTabulator->terminalHolder();
if (ch)
cfg.provideCurrentDirectory(ch->currentTerminal()->impl()->workingDirectory());
MainWindow *w = new MainWindow(cfg, false);
w->show();
}
void MainWindow::bookmarksWidget_callCommand(const QString& cmd)
{
consoleTabulator->terminalHolder()->currentTerminal()->impl()->sendText(cmd);
consoleTabulator->terminalHolder()->currentTerminal()->setFocus();
}
void MainWindow::bookmarksDock_visibilityChanged(bool visible)
{
Properties::Instance()->bookmarksVisible = visible;
}
void MainWindow::addNewTab()
{
TerminalConfig cfg;
if (Properties::Instance()->terminalsPreset == 3)
consoleTabulator->preset4Terminals();
else if (Properties::Instance()->terminalsPreset == 2)
consoleTabulator->preset2Vertical();
else if (Properties::Instance()->terminalsPreset == 1)
consoleTabulator->preset2Horizontal();
else
consoleTabulator->addNewTab(cfg);
updateDisabledActions();
}
void MainWindow::onCurrentTitleChanged(int index)
{
QString title;
QIcon icon;
if (-1 != index)
{
title = consoleTabulator->tabText(index);
icon = consoleTabulator->tabIcon(index);
}
setWindowTitle(title.isEmpty() || !Properties::Instance()->changeWindowTitle ? QStringLiteral("QTerminal") : title);
setWindowIcon(icon.isNull() || !Properties::Instance()->changeWindowIcon ? QIcon::fromTheme("utilities-terminal") : icon);
}
bool MainWindow::hasMultipleTabs()
{
return consoleTabulator->findChildren<TermWidgetHolder*>().count() > 1;
}
bool MainWindow::hasMultipleSubterminals()
{
return consoleTabulator->terminalHolder()->findChildren<TermWidget*>().count() > 1;
}
void MainWindow::updateDisabledActions()
{
const QList<QAction*> actions = menu_Actions->actions();
for (QAction *action : actions) {
if (!action->data().isNull()) {
const checkfn check = action->data().value<checkfn>();
action->setEnabled(check(*this));
}
}
}
QMap< QString, QAction * >& MainWindow::leaseActions() {
return actions;
}
#ifdef HAVE_QDBUS
QDBusObjectPath MainWindow::getActiveTab()
{
return qobject_cast<TermWidgetHolder*>(consoleTabulator->currentWidget())->getDbusPath();
}
QList<QDBusObjectPath> MainWindow::getTabs()
{
QList<QDBusObjectPath> tabs;
for (int i = 0; i<consoleTabulator->count(); ++i)
{
tabs.push_back(qobject_cast<TermWidgetHolder*>(consoleTabulator->widget(i))->getDbusPath());
}
return tabs;
}
QDBusObjectPath MainWindow::newTab(const QHash<QString,QVariant> &termArgs)
{
TerminalConfig cfg = TerminalConfig::fromDbus(termArgs);
int idx = consoleTabulator->addNewTab(cfg);
return qobject_cast<TermWidgetHolder*>(consoleTabulator->widget(idx))->getDbusPath();
}
void MainWindow::closeWindow()
{
close();
}
#endif

@ -1,123 +0,0 @@
/***************************************************************************
* Copyright (C) 2006 by Vladimir Kuznetsov *
* vovanec@gmail.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "ui_qterminal.h"
#include <QMainWindow>
#include <QAction>
#include "qxtglobalshortcut.h"
#include "terminalconfig.h"
#include "dbusaddressable.h"
class QToolButton;
class MainWindow : public QMainWindow, private Ui::mainWindow, public DBusAddressable
{
Q_OBJECT
public:
MainWindow(TerminalConfig& cfg,
bool dropMode,
QWidget * parent = 0, Qt::WindowFlags f = 0);
~MainWindow();
bool dropMode() { return m_dropMode; }
QMap<QString, QAction*> & leaseActions();
#ifdef HAVE_QDBUS
QDBusObjectPath getActiveTab();
QList<QDBusObjectPath> getTabs();
QDBusObjectPath newTab(const QHash<QString,QVariant> &termArgs);
void closeWindow();
#endif
protected:
bool event(QEvent* event);
private:
QActionGroup *tabPosition, *scrollBarPosition, *keyboardCursorShape;
QMenu *tabPosMenu, *scrollPosMenu, *keyboardCursorShapeMenu;
// A parent object for QObjects that are created dynamically based on settings
// Used to simplify the setting cleanup on reconfiguration: deleting settingOwner frees all related QObjects
QWidget *settingOwner;
QMenu *presetsMenu;
bool m_removeFinished;
TerminalConfig m_config;
QDockWidget *m_bookmarksDock;
void setup_Action(const char *name, QAction *action, const char *defaultShortcut, const QObject *receiver,
const char *slot, QMenu *menu = NULL, const QVariant &data = QVariant());
QMap< QString, QAction * > actions;
void rebuildActions();
void setup_FileMenu_Actions();
void setup_ActionsMenu_Actions();
void setup_ViewMenu_Actions();
void setup_ContextMenu_Actions();
void setupCustomDirs();
void closeEvent(QCloseEvent*);
void enableDropMode();
QToolButton *m_dropLockButton;
bool m_dropMode;
QxtGlobalShortcut m_dropShortcut;
void realign();
void setDropShortcut(QKeySequence dropShortCut);
bool hasMultipleTabs();
bool hasMultipleSubterminals();
public slots:
void showHide();
void updateDisabledActions();
private slots:
void on_consoleTabulator_currentChanged(int);
void propertiesChanged();
void actAbout_triggered();
void actProperties_triggered();
void updateActionGroup(QAction *);
void testClose(bool removeFinished);
void toggleBookmarks();
void toggleBorderless();
void toggleTabBar();
void toggleMenu();
void showFullscreen(bool fullscreen);
void setKeepOpen(bool value);
void find();
void newTerminalWindow();
void bookmarksWidget_callCommand(const QString&);
void bookmarksDock_visibilityChanged(bool visible);
void addNewTab();
void onCurrentTitleChanged(int index);
};
#endif //MAINWINDOW_H

@ -1,23 +0,0 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.lxqt.QTerminal.Process">
<method name="getWindows">
<arg name="windows" type="ao" direction="out"/>
</method>
<method name="newWindow">
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="QHash&lt;QString,QVariant&gt;"/>
<arg name="termArgs" type="a{sv}" direction="in"/>
</method>
<method name="getActiveWindow">
<arg name="window" type="o" direction="out"/>
</method>
<method name="isDropMode">
<arg name="isDropMode" type="b" direction="out"/>
</method>
<method name="toggleDropdown">
<arg name="success" type="b" direction="out"/>
</method>
</interface>
</node>

@ -1,17 +0,0 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.lxqt.QTerminal.Tab">
<method name="getActiveTerminal">
<arg name="terminal" type="o" direction="out"/>
</method>
<method name="getTerminals">
<arg name="terminals" type="ao" direction="out"/>
</method>
<method name="getWindow">
<arg name="window" type="o" direction="out"/>
</method>
<method name="closeTab"/>
</interface>
</node>

@ -1,24 +0,0 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.lxqt.QTerminal.Terminal">
<method name="splitVertical">
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="QHash&lt;QString,QVariant&gt;"/>
<arg name="termArgs" type="a{sv}" direction="in"/>
<arg name="newTerminal" type="o" direction="out"/>
</method>
<method name="splitHorizontal">
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="QHash&lt;QString,QVariant&gt;"/>
<arg name="termArgs" type="a{sv}" direction="in"/>
<arg name="newTerminal" type="o" direction="out"/>
</method>
<method name="getTab">
<arg name="tab" type="o" direction="out"/>
</method>
<method name="sendText">
<arg name="text" type="s" direction="in"/>
</method>
<method name="closeTerminal"/>
</interface>
</node>

@ -1,20 +0,0 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.lxqt.QTerminal.Window">
<method name="getTabs">
<arg name="tabs" type="ao" direction="out"/>
</method>
<method name="getActiveTab">
<arg name="tab" type="o" direction="out"/>
</method>
<method name="newTab">
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="QHash&lt;QString,QVariant&gt;"/>
<arg name="termArgs" type="a{sv}" direction="in"/>
<arg name="newTerminal" type="o" direction="out"/>
</method>
<method name="closeWindow"/>
<method name="activateWindow"/>
</interface>
</node>

@ -1,322 +0,0 @@
/***************************************************************************
* Copyright (C) 2010 by Petr Vanek *
* petr@scribus.info *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include <qtermwidget.h>
#include <assert.h>
#include "properties.h"
#include "config.h"
#include "mainwindow.h"
#include "qterminalapp.h"
Properties * Properties::m_instance = 0;
Properties * Properties::Instance(const QString& filename)
{
if (!m_instance)
m_instance = new Properties(filename);
return m_instance;
}
Properties::Properties(const QString& filename)
: filename(filename)
{
if (filename.isEmpty())
m_settings = new QSettings();
else
m_settings = new QSettings(filename);
qDebug("Properties constructor called");
}
Properties::~Properties()
{
qDebug("Properties destructor called");
delete m_settings;
m_instance = 0;
}
QFont Properties::defaultFont()
{
QFont default_font = QApplication::font();
default_font.setFamily(DEFAULT_FONT);
default_font.setPointSize(12);
default_font.setStyleHint(QFont::TypeWriter);
return default_font;
}
void Properties::loadSettings()
{
guiStyle = m_settings->value("guiStyle", QString()).toString();
if (!guiStyle.isNull())
QApplication::setStyle(guiStyle);
colorScheme = m_settings->value("colorScheme", "Linux").toString();
highlightCurrentTerminal = m_settings->value("highlightCurrentTerminal", true).toBool();
showTerminalSizeHint = m_settings->value("showTerminalSizeHint", true).toBool();
font = QFont(qvariant_cast<QString>(m_settings->value("fontFamily", defaultFont().family())),
qvariant_cast<int>(m_settings->value("fontSize", defaultFont().pointSize())));
//Legacy font setting
font = qvariant_cast<QFont>(m_settings->value("font", font));
mainWindowSize = m_settings->value("MainWindow/size").toSize();
mainWindowPosition = m_settings->value("MainWindow/pos").toPoint();
mainWindowState = m_settings->value("MainWindow/state").toByteArray();
historyLimited = m_settings->value("HistoryLimited", true).toBool();
historyLimitedTo = m_settings->value("HistoryLimitedTo", 1000).toUInt();
emulation = m_settings->value("emulation", "default").toString();
// sessions
int size = m_settings->beginReadArray("Sessions");
for (int i = 0; i < size; ++i)
{
m_settings->setArrayIndex(i);
QString name(m_settings->value("name").toString());
if (name.isEmpty())
continue;
sessions[name] = m_settings->value("state").toByteArray();
}
m_settings->endArray();
appTransparency = m_settings->value("MainWindow/ApplicationTransparency", 0).toInt();
termTransparency = m_settings->value("TerminalTransparency", 0).toInt();
backgroundImage = m_settings->value("TerminalBackgroundImage", QString()).toString();
/* default to Right. see qtermwidget.h */
scrollBarPos = m_settings->value("ScrollbarPosition", 2).toInt();
/* default to North. I'd prefer South but North is standard (they say) */
tabsPos = m_settings->value("TabsPosition", 0).toInt();
/* default to BlockCursor */
keyboardCursorShape = m_settings->value("KeyboardCursorShape", 0).toInt();
hideTabBarWithOneTab = m_settings->value("HideTabBarWithOneTab", false).toBool();
m_motionAfterPaste = m_settings->value("MotionAfterPaste", 0).toInt();
/* tab width limit */
limitTabWidth = m_settings->value("LimitTabWidth", true).toBool();
limitTabWidthValue = m_settings->value("LimitTabWidthValue", 500).toInt();
showCloseTabButton = m_settings->value("ShowCloseTabButton", true).toBool();
/* toggles */
borderless = m_settings->value("Borderless", false).toBool();
tabBarless = m_settings->value("TabBarless", false).toBool();
menuVisible = m_settings->value("MenuVisible", true).toBool();
askOnExit = m_settings->value("AskOnExit", true).toBool();
saveSizeOnExit = m_settings->value("SaveSizeOnExit", true).toBool();
savePosOnExit = m_settings->value("SavePosOnExit", true).toBool();
useCWD = m_settings->value("UseCWD", false).toBool();
term = m_settings->value("Term", "xterm-256color").toString();
// bookmarks
useBookmarks = m_settings->value("UseBookmarks", false).toBool();
bookmarksVisible = m_settings->value("BookmarksVisible", true).toBool();
const QString s = QFileInfo(m_settings->fileName()).canonicalPath() + QString::fromLatin1("/qterminal_bookmarks.xml");
bookmarksFile = m_settings->value("BookmarksFile", s).toString();
terminalsPreset = m_settings->value("TerminalsPreset", 0).toInt();
m_settings->beginGroup("DropMode");
dropShortCut = QKeySequence(m_settings->value("ShortCut", "F12").toString());
dropKeepOpen = m_settings->value("KeepOpen", false).toBool();
dropShowOnStart = m_settings->value("ShowOnStart", true).toBool();
dropWidht = m_settings->value("Width", 70).toInt();
dropHeight = m_settings->value("Height", 45).toInt();
m_settings->endGroup();
changeWindowTitle = m_settings->value("ChangeWindowTitle", true).toBool();
changeWindowIcon = m_settings->value("ChangeWindowIcon", true).toBool();
enabledBidiSupport = m_settings->value("enabledBidiSupport", true).toBool();
confirmMultilinePaste = m_settings->value("ConfirmMultilinePaste", false).toBool();
trimPastedTrailingNewlines = m_settings->value("TrimPastedTrailingNewlines", false).toBool();
}
void Properties::saveSettings()
{
m_settings->setValue("guiStyle", guiStyle);
m_settings->setValue("colorScheme", colorScheme);
m_settings->setValue("highlightCurrentTerminal", highlightCurrentTerminal);
m_settings->setValue("showTerminalSizeHint", showTerminalSizeHint);
m_settings->setValue("fontFamily", font.family());
m_settings->setValue("fontSize", font.pointSize());
//Clobber legacy setting
m_settings->remove("font");
m_settings->beginGroup("Shortcuts");
MainWindow *mainWindow = QTerminalApp::Instance()->getWindowList()[0];
assert(mainWindow != NULL);
QMapIterator< QString, QAction * > it(mainWindow->leaseActions());
while( it.hasNext() )
{
it.next();
QStringList sequenceStrings;
const auto shortcuts = it.value()->shortcuts();
for (const QKeySequence &shortcut : shortcuts)
sequenceStrings.append(shortcut.toString());
m_settings->setValue(it.key(), sequenceStrings.join('|'));
}
m_settings->endGroup();
m_settings->setValue("MainWindow/size", mainWindowSize);
m_settings->setValue("MainWindow/pos", mainWindowPosition);
m_settings->setValue("MainWindow/state", mainWindowState);
m_settings->setValue("HistoryLimited", historyLimited);
m_settings->setValue("HistoryLimitedTo", historyLimitedTo);
m_settings->setValue("emulation", emulation);
// sessions
m_settings->beginWriteArray("Sessions");
int i = 0;
Sessions::iterator sit = sessions.begin();
while (sit != sessions.end())
{
m_settings->setArrayIndex(i);
m_settings->setValue("name", sit.key());
m_settings->setValue("state", sit.value());
++sit;
++i;
}
m_settings->endArray();
m_settings->setValue("MainWindow/ApplicationTransparency", appTransparency);
m_settings->setValue("TerminalTransparency", termTransparency);
m_settings->setValue("TerminalBackgroundImage", backgroundImage);
m_settings->setValue("ScrollbarPosition", scrollBarPos);
m_settings->setValue("TabsPosition", tabsPos);
m_settings->setValue("KeyboardCursorShape", keyboardCursorShape);
m_settings->setValue("HideTabBarWithOneTab", hideTabBarWithOneTab);
m_settings->setValue("MotionAfterPaste", m_motionAfterPaste);
m_settings->setValue("LimitTabWidth", limitTabWidth);
m_settings->setValue("LimitTabWidthValue", limitTabWidthValue);
m_settings->setValue("ShowCloseTabButton", showCloseTabButton);
m_settings->setValue("Borderless", borderless);
m_settings->setValue("TabBarless", tabBarless);
m_settings->setValue("MenuVisible", menuVisible);
m_settings->setValue("AskOnExit", askOnExit);
m_settings->setValue("SavePosOnExit", savePosOnExit);
m_settings->setValue("SaveSizeOnExit", saveSizeOnExit);
m_settings->setValue("UseCWD", useCWD);
m_settings->setValue("Term", term);
// bookmarks
m_settings->setValue("UseBookmarks", useBookmarks);
m_settings->setValue("BookmarksVisible", bookmarksVisible);
m_settings->setValue("BookmarksFile", bookmarksFile);
m_settings->setValue("TerminalsPreset", terminalsPreset);
m_settings->beginGroup("DropMode");
m_settings->setValue("ShortCut", dropShortCut.toString());
m_settings->setValue("KeepOpen", dropKeepOpen);
m_settings->setValue("ShowOnStart", dropShowOnStart);
m_settings->setValue("Width", dropWidht);
m_settings->setValue("Height", dropHeight);
m_settings->endGroup();
m_settings->setValue("ChangeWindowTitle", changeWindowTitle);
m_settings->setValue("ChangeWindowIcon", changeWindowIcon);
m_settings->setValue("enabledBidiSupport", enabledBidiSupport);
m_settings->setValue("ConfirmMultilinePaste", confirmMultilinePaste);
m_settings->setValue("TrimPastedTrailingNewlines", trimPastedTrailingNewlines);
}
void Properties::migrate_settings()
{
// Deal with rearrangements of settings.
// If this method becomes unbearably huge we should look at the config-update
// system used by kde and razor.
QSettings settings;
QString lastVersion = settings.value("version", "0.0.0").toString();
QString currentVersion = STR_VERSION;
if (currentVersion < lastVersion)
{
qDebug() << "Warning: Configuration file was written by a newer version "
<< "of QTerminal. Some settings might be incompatible";
}
if (lastVersion < "0.4.0")
{
// ===== Paste Selection -> Paste Clipboard =====
settings.beginGroup("Shortcuts");
if(!settings.contains(PASTE_CLIPBOARD))
{
QString value = settings.value("Paste Selection", PASTE_CLIPBOARD_SHORTCUT).toString();
settings.setValue(PASTE_CLIPBOARD, value);
}
settings.remove("Paste Selection");
settings.endGroup();
}
if (lastVersion <= "0.6.0")
{
// ===== AlwaysShowTabs -> HideTabBarWithOneTab =====
if(!settings.contains("HideTabBarWithOneTab"))
{
QString hideValue = settings.value("AlwaysShowTabs", false).toString();
settings.setValue("HideTabBarWithOneTab", hideValue);
}
settings.remove("AlwaysShowTabs");
// ===== appOpacity -> ApplicationTransparency =====
//
// Note: In 0.6.0 the opacity values had been erroneously
// restricted to [0,99] instead of [1,100]. We fix this here by
// setting the opacity to 100 if it was 99 and to 1 if it was 0.
//
if(!settings.contains("MainWindow/ApplicationTransparency"))
{
int appOpacityValue = settings.value("MainWindow/appOpacity", 100).toInt();
appOpacityValue = appOpacityValue == 99 ? 100 : appOpacityValue;
appOpacityValue = appOpacityValue == 0 ? 1 : appOpacityValue;
settings.setValue("MainWindow/ApplicationTransparency", 100 - appOpacityValue);
}
settings.remove("MainWindow/appOpacity");
// ===== termOpacity -> TerminalTransparency =====
if(!settings.contains("TerminalTransparency"))
{
int termOpacityValue = settings.value("termOpacity", 100).toInt();
termOpacityValue = termOpacityValue == 99 ? 100 : termOpacityValue;
settings.setValue("TerminalTransparency", 100 - termOpacityValue);
}
settings.remove("termOpacity");
// geometry -> size, pos
if (!settings.contains("MainWindow/size"))
{
QWidget geom;
geom.restoreGeometry(settings.value("MainWindow/geometry").toByteArray());
settings.setValue("MainWindow/size", geom.size());
settings.setValue("MainWindow/pos", geom.pos());
settings.remove("MainWindow/geometry");
}
}
if (currentVersion > lastVersion)
settings.setValue("version", currentVersion);
}

@ -1,124 +0,0 @@
/***************************************************************************
* Copyright (C) 2010 by Petr Vanek *
* petr@scribus.info *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef PROPERTIES_H
#define PROPERTIES_H
#include <QApplication>
#include <QtCore>
#include <QFont>
typedef QString Session;
typedef QMap<QString,Session> Sessions;
typedef QMap<QString,QString> ShortcutMap;
class Properties
{
public:
static Properties *Instance(const QString& filename = QString());
~Properties();
QFont defaultFont();
void saveSettings();
void loadSettings();
void migrate_settings();
QSize mainWindowSize;
QPoint mainWindowPosition;
QByteArray mainWindowState;
//ShortcutMap shortcuts;
QString shell;
QFont font;
QString colorScheme;
QString guiStyle;
bool highlightCurrentTerminal;
bool showTerminalSizeHint;
bool historyLimited;
unsigned historyLimitedTo;
QString emulation;
Sessions sessions;
int appTransparency;
int termTransparency;
QString backgroundImage;
int scrollBarPos;
int tabsPos;
int keyboardCursorShape;
bool hideTabBarWithOneTab;
int m_motionAfterPaste;
bool limitTabWidth;
int limitTabWidthValue;
bool showCloseTabButton;
bool borderless;
bool tabBarless;
bool menuVisible;
bool askOnExit;
bool saveSizeOnExit;
bool savePosOnExit;
bool useCWD;
QString term;
bool useBookmarks;
bool bookmarksVisible;
QString bookmarksFile;
int terminalsPreset;
QKeySequence dropShortCut;
bool dropKeepOpen;
bool dropShowOnStart;
int dropWidht;
int dropHeight;
bool changeWindowTitle;
bool changeWindowIcon;
bool enabledBidiSupport;
bool confirmMultilinePaste;
bool trimPastedTrailingNewlines;
private:
// Singleton handling
static Properties *m_instance;
QString filename;
explicit Properties(const QString& filename);
Properties(const Properties &) {};
QSettings *m_settings;
};
#endif

@ -1,435 +0,0 @@
/***************************************************************************
* Copyright (C) 2010 by Petr Vanek *
* petr@scribus.info *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include <qtermwidget.h>
#include <QDebug>
#include <QStyleFactory>
#include <QFileDialog>
#include <QKeySequenceEdit>
#include "propertiesdialog.h"
#include "properties.h"
#include "fontdialog.h"
#include "config.h"
#include "qterminalapp.h"
Delegate::Delegate (QObject *parent)
: QStyledItemDelegate (parent)
{
}
QWidget* Delegate::createEditor(QWidget *parent,
const QStyleOptionViewItem& /*option*/,
const QModelIndex& /*index*/) const
{
return new QKeySequenceEdit (parent);
}
bool Delegate::eventFilter(QObject *object, QEvent *event)
{
QWidget *editor = qobject_cast<QWidget*>(object);
if (editor && event->type() == QEvent::KeyPress) {
int k = static_cast<QKeyEvent *>(event)->key();
if (k == Qt::Key_Return || k == Qt::Key_Enter) {
emit QAbstractItemDelegate::commitData(editor);
emit QAbstractItemDelegate::closeEditor(editor);
return true;
}
}
return QStyledItemDelegate::eventFilter (object, event);
}
PropertiesDialog::PropertiesDialog(QWidget *parent)
: QDialog(parent)
{
setupUi(this);
connect(buttonBox->button(QDialogButtonBox::Apply), &QPushButton::clicked,
this, &PropertiesDialog::apply);
connect(changeFontButton, &QPushButton::clicked,
this, &PropertiesDialog::changeFontButton_clicked);
connect(chooseBackgroundImageButton, &QPushButton::clicked,
this, &PropertiesDialog::chooseBackgroundImageButton_clicked);
QStringList emulations = QTermWidget::availableKeyBindings();
QStringList colorSchemes = QTermWidget::availableColorSchemes();
colorSchemes.sort(Qt::CaseInsensitive);
listWidget->setCurrentRow(0);
listWidget->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContentsOnFirstShow);
colorSchemaCombo->addItems(colorSchemes);
int csix = colorSchemaCombo->findText(Properties::Instance()->colorScheme);
if (csix != -1)
colorSchemaCombo->setCurrentIndex(csix);
backgroundImageLineEdit->setText(Properties::Instance()->backgroundImage);
emulationComboBox->addItems(emulations);
int eix = emulationComboBox->findText(Properties::Instance()->emulation);
emulationComboBox->setCurrentIndex(eix != -1 ? eix : 0 );
/* set the delegate of shortcut widget as well as its contents */
Delegate *del = new Delegate(shortcutsWidget);
shortcutsWidget->setItemDelegate(del);
shortcutsWidget->sortByColumn(0, Qt::AscendingOrder);
setupShortcuts();
/* scrollbar position */
QStringList scrollBarPosList;
scrollBarPosList << tr("No scrollbar") << tr("Left") << tr("Right");
scrollBarPos_comboBox->addItems(scrollBarPosList);
scrollBarPos_comboBox->setCurrentIndex(Properties::Instance()->scrollBarPos);
/* tabs position */
QStringList tabsPosList;
tabsPosList << tr("Top") << tr("Bottom") << tr("Left") << tr("Right");
tabsPos_comboBox->addItems(tabsPosList);
tabsPos_comboBox->setCurrentIndex(Properties::Instance()->tabsPos);
/* tab width */
limitTabWidthCheckBox->setChecked(Properties::Instance()->limitTabWidth);
limitTabWidthSpinBox->setValue(Properties::Instance()->limitTabWidthValue);
closeTabButtonCheckBox->setChecked(Properties::Instance()->showCloseTabButton);
/* keyboard cursor shape */
QStringList keyboardCursorShapeList;
keyboardCursorShapeList << tr("BlockCursor") << tr("UnderlineCursor") << tr("IBeamCursor");
keybCursorShape_comboBox->addItems(keyboardCursorShapeList);
keybCursorShape_comboBox->setCurrentIndex(Properties::Instance()->keyboardCursorShape);
hideTabBarCheckBox->setChecked(Properties::Instance()->hideTabBarWithOneTab);
// show main menu bar
showMenuCheckBox->setChecked(Properties::Instance()->menuVisible);
/* actions by motion after paste */
QStringList motionAfter;
motionAfter << tr("No move") << tr("Move start") << tr("Move end");
motionAfterPasting_comboBox->addItems(motionAfter);
motionAfterPasting_comboBox->setCurrentIndex(Properties::Instance()->m_motionAfterPaste);
// Setting windows style actions
styleComboBox->addItem(tr("System Default"));
styleComboBox->addItems(QStyleFactory::keys());
int ix = styleComboBox->findText(Properties::Instance()->guiStyle);
if (ix != -1)
styleComboBox->setCurrentIndex(ix);
setFontSample(Properties::Instance()->font);
appTransparencyBox->setValue(Properties::Instance()->appTransparency);
termTransparencyBox->setValue(Properties::Instance()->termTransparency);
highlightCurrentCheckBox->setChecked(Properties::Instance()->highlightCurrentTerminal);
showTerminalSizeHintCheckBox->setChecked(Properties::Instance()->showTerminalSizeHint);
askOnExitCheckBox->setChecked(Properties::Instance()->askOnExit);
savePosOnExitCheckBox->setChecked(Properties::Instance()->savePosOnExit);
saveSizeOnExitCheckBox->setChecked(Properties::Instance()->saveSizeOnExit);
useCwdCheckBox->setChecked(Properties::Instance()->useCWD);
termComboBox->setCurrentText(Properties::Instance()->term);
historyLimited->setChecked(Properties::Instance()->historyLimited);
historyUnlimited->setChecked(!Properties::Instance()->historyLimited);
historyLimitedTo->setValue(Properties::Instance()->historyLimitedTo);
dropShowOnStartCheckBox->setChecked(Properties::Instance()->dropShowOnStart);
dropHeightSpinBox->setValue(Properties::Instance()->dropHeight);
dropHeightSpinBox->setMaximum(100);
dropWidthSpinBox->setValue(Properties::Instance()->dropWidht);
dropWidthSpinBox->setMaximum(100);
dropShortCutEdit->setText(Properties::Instance()->dropShortCut.toString());
useBookmarksCheckBox->setChecked(Properties::Instance()->useBookmarks);
bookmarksLineEdit->setText(Properties::Instance()->bookmarksFile);
openBookmarksFile(Properties::Instance()->bookmarksFile);
connect(bookmarksButton, &QPushButton::clicked,
this, &PropertiesDialog::bookmarksButton_clicked);
terminalPresetComboBox->setCurrentIndex(Properties::Instance()->terminalsPreset);
changeWindowTitleCheckBox->setChecked(Properties::Instance()->changeWindowTitle);
changeWindowIconCheckBox->setChecked(Properties::Instance()->changeWindowIcon);
enabledBidiSupportCheckBox->setChecked(Properties::Instance()->enabledBidiSupport);
trimPastedTrailingNewlinesCheckBox->setChecked(Properties::Instance()->trimPastedTrailingNewlines);
confirmMultilinePasteCheckBox->setChecked(Properties::Instance()->confirmMultilinePaste);
}
PropertiesDialog::~PropertiesDialog()
{
}
void PropertiesDialog::accept()
{
apply();
QDialog::accept();
}
void PropertiesDialog::apply()
{
Properties::Instance()->colorScheme = colorSchemaCombo->currentText();
Properties::Instance()->font = fontSampleLabel->font();//fontComboBox->currentFont();
Properties::Instance()->guiStyle = (styleComboBox->currentText() == tr("System Default")) ?
QString() : styleComboBox->currentText();
Properties::Instance()->emulation = emulationComboBox->currentText();
/* do not allow to go above 99 or we lose transparency option */
(appTransparencyBox->value() >= 100) ?
Properties::Instance()->appTransparency = 99
:
Properties::Instance()->appTransparency = appTransparencyBox->value();
Properties::Instance()->termTransparency = termTransparencyBox->value();
Properties::Instance()->highlightCurrentTerminal = highlightCurrentCheckBox->isChecked();
Properties::Instance()->showTerminalSizeHint = showTerminalSizeHintCheckBox->isChecked();
Properties::Instance()->backgroundImage = backgroundImageLineEdit->text();
Properties::Instance()->askOnExit = askOnExitCheckBox->isChecked();
Properties::Instance()->savePosOnExit = savePosOnExitCheckBox->isChecked();
Properties::Instance()->saveSizeOnExit = saveSizeOnExitCheckBox->isChecked();
Properties::Instance()->useCWD = useCwdCheckBox->isChecked();
Properties::Instance()->term = termComboBox->currentText();
Properties::Instance()->scrollBarPos = scrollBarPos_comboBox->currentIndex();
Properties::Instance()->tabsPos = tabsPos_comboBox->currentIndex();
Properties::Instance()->limitTabWidth = limitTabWidthCheckBox->isChecked();
Properties::Instance()->limitTabWidthValue = limitTabWidthSpinBox->value();
Properties::Instance()->keyboardCursorShape = keybCursorShape_comboBox->currentIndex();
Properties::Instance()->showCloseTabButton = closeTabButtonCheckBox->isChecked();
Properties::Instance()->hideTabBarWithOneTab = hideTabBarCheckBox->isChecked();
Properties::Instance()->menuVisible = showMenuCheckBox->isChecked();
Properties::Instance()->m_motionAfterPaste = motionAfterPasting_comboBox->currentIndex();
Properties::Instance()->historyLimited = historyLimited->isChecked();
Properties::Instance()->historyLimitedTo = historyLimitedTo->value();
saveShortcuts();
Properties::Instance()->saveSettings();
Properties::Instance()->dropShowOnStart = dropShowOnStartCheckBox->isChecked();
Properties::Instance()->dropHeight = dropHeightSpinBox->value();
Properties::Instance()->dropWidht = dropWidthSpinBox->value();
Properties::Instance()->dropShortCut = QKeySequence(dropShortCutEdit->text());
Properties::Instance()->useBookmarks = useBookmarksCheckBox->isChecked();
Properties::Instance()->bookmarksFile = bookmarksLineEdit->text();
saveBookmarksFile(Properties::Instance()->bookmarksFile);
Properties::Instance()->terminalsPreset = terminalPresetComboBox->currentIndex();
Properties::Instance()->changeWindowTitle = changeWindowTitleCheckBox->isChecked();
Properties::Instance()->changeWindowIcon = changeWindowIconCheckBox->isChecked();
Properties::Instance()->enabledBidiSupport = enabledBidiSupportCheckBox->isChecked();
Properties::Instance()->trimPastedTrailingNewlines = trimPastedTrailingNewlinesCheckBox->isChecked();
Properties::Instance()->confirmMultilinePaste = confirmMultilinePasteCheckBox->isChecked();
emit propertiesChanged();
}
void PropertiesDialog::setFontSample(const QFont & f)
{
fontSampleLabel->setFont(f);
QString sample("%1 %2 pt");
fontSampleLabel->setText(sample.arg(f.family()).arg(f.pointSize()));
}
void PropertiesDialog::changeFontButton_clicked()
{
FontDialog dia(fontSampleLabel->font());
if (!dia.exec())
return;
QFont f = dia.getFont();
if (QFontInfo(f).fixedPitch())
setFontSample(f);
}
void PropertiesDialog::chooseBackgroundImageButton_clicked()
{
QString filename = QFileDialog::getOpenFileName(
this, tr("Choose a background image"),
QString(), tr("Images (*.bmp *.png *.xpm *.jpg)"));
if (!filename.isNull())
backgroundImageLineEdit->setText(filename);
}
void PropertiesDialog::saveShortcuts()
{
QMap<QString, QAction*> actions = QTerminalApp::Instance()->getWindowList()[0]->leaseActions();
QList< QString > shortcutKeys = actions.keys();
int shortcutCount = shortcutKeys.count();
shortcutsWidget->setRowCount( shortcutCount );
for( int x=0; x < shortcutCount; x++ )
{
QString keyValue = shortcutKeys.at(x);
QAction *keyAction = actions[keyValue];
QTableWidgetItem *item = shortcutsWidget->item(x, 1);
QKeySequence sequence = QKeySequence(item->text());
QString sequenceString = sequence.toString();
QList<QKeySequence> shortcuts;
const auto sequences = item->text().split('|');
for (const QKeySequence& sequenceString : sequences)
shortcuts.append(QKeySequence(sequenceString));
keyAction->setShortcuts(shortcuts);
}
Properties::Instance()->saveSettings();
}
void PropertiesDialog::setupShortcuts()
{
QMap<QString, QAction*> actions = QTerminalApp::Instance()->getWindowList()[0]->leaseActions();
QList< QString > shortcutKeys = actions.keys();
int shortcutCount = shortcutKeys.count();
shortcutsWidget->setRowCount( shortcutCount );
for( int x=0; x < shortcutCount; x++ )
{
QString keyValue = shortcutKeys.at(x);
QAction *keyAction = actions[keyValue];
QStringList sequenceStrings;
const auto shortcuts = keyAction->shortcuts();
for (const QKeySequence &shortcut : shortcuts)
sequenceStrings.append(shortcut.toString());
QTableWidgetItem *itemName = new QTableWidgetItem( tr(keyValue.toStdString().c_str()) );
QTableWidgetItem *itemShortcut = new QTableWidgetItem( sequenceStrings.join('|') );
itemName->setFlags( itemName->flags() & ~Qt::ItemIsEditable & ~Qt::ItemIsSelectable );
shortcutsWidget->setItem(x, 0, itemName);
shortcutsWidget->setItem(x, 1, itemShortcut);
}
shortcutsWidget->resizeColumnsToContents();
// No shortcut validation is needed with QKeySequenceEdit.
}
void PropertiesDialog::bookmarksButton_clicked()
{
QFileDialog dia(this, tr("Open or create bookmarks file"));
dia.setConfirmOverwrite(false);
dia.setFileMode(QFileDialog::AnyFile);
if (!dia.exec())
return;
QString fname = dia.selectedFiles().count() ? dia.selectedFiles().at(0) : QString();
if (fname.isNull())
return;
bookmarksLineEdit->setText(fname);
openBookmarksFile(bookmarksLineEdit->text());
}
void PropertiesDialog::openBookmarksFile(const QString &fname)
{
QFile f(fname);
QString content;
if (!f.open(QFile::ReadOnly))
content = "<qterminal>\n <group name=\"group1\">\n <command name=\"cmd1\" value=\"cd $HOME\"/>\n </group>\n</qterminal>";
else
content = f.readAll();
bookmarkPlainEdit->setPlainText(content);
bookmarkPlainEdit->document()->setModified(false);
}
void PropertiesDialog::saveBookmarksFile(const QString &fname)
{
if (!bookmarkPlainEdit->document()->isModified())
return;
QFile f(fname);
if (!f.open(QFile::WriteOnly|QFile::Truncate))
qDebug() << "Cannot write to file" << f.fileName();
else
f.write(bookmarkPlainEdit->toPlainText().toUtf8());
}
/*
void PropertiesDialog::setupShortcuts()
{
QList< QString > shortcutKeys = Properties::Instance()->shortcuts.keys();
int shortcutCount = shortcutKeys.count();
shortcutsWidget->setRowCount( shortcutCount );
for( int x=0; x < shortcutCount; x++ )
{
QString keyValue = shortcutKeys.at(x);
QLabel *lblShortcut = new QLabel( keyValue, this );
QPushButton *btnLaunch = new QPushButton( Properties::Instance()->shortcuts.value( keyValue ), this );
btnLaunch->setObjectName(keyValue);
connect( btnLaunch, SIGNAL(clicked()), this, SLOT(shortcutPrompt()) );
shortcutsWidget->setCellWidget( x, 0, lblShortcut );
shortcutsWidget->setCellWidget( x, 1, btnLaunch );
}
}
void PropertiesDialog::shortcutPrompt()
{
QObject *objectSender = sender();
if( !objectSender )
return;
QString name = objectSender->objectName();
qDebug() << "shortcutPrompt(" << name << ")";
DialogShortcut *dlgShortcut = new DialogShortcut(this);
dlgShortcut->setTitle( tr("Select a key sequence for %1").arg(name) );
QString sequenceString = Properties::Instance()->shortcuts[name];
dlgShortcut->setKey(sequenceString);
int result = dlgShortcut->exec();
if( result == QDialog::Accepted )
{
sequenceString = dlgShortcut->getKey();
Properties::Instance()->shortcuts[name] = sequenceString;
Properties::Instance()->saveSettings();
}
}
*/

@ -1,71 +0,0 @@
/***************************************************************************
* Copyright (C) 2010 by Petr Vanek *
* petr@scribus.info *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef PROPERTIESDIALOG_H
#define PROPERTIESDIALOG_H
#include <QStyledItemDelegate>
#include "ui_propertiesdialog.h"
class Delegate : public QStyledItemDelegate
{
Q_OBJECT
public:
Delegate (QObject *parent = 0);
virtual QWidget* createEditor(QWidget *parent,
const QStyleOptionViewItem&,
const QModelIndex&) const;
virtual bool eventFilter(QObject *object, QEvent *event);
};
class PropertiesDialog : public QDialog, Ui::PropertiesDialog
{
Q_OBJECT
QString oldAccelText; // Placeholder when editing shortcut
public:
PropertiesDialog(QWidget *parent=NULL);
~PropertiesDialog();
signals:
void propertiesChanged();
private:
void setFontSample(const QFont & f);
void openBookmarksFile(const QString &fname);
void saveBookmarksFile(const QString &fname);
private slots:
void apply();
void accept();
void changeFontButton_clicked();
void chooseBackgroundImageButton_clicked();
void bookmarksButton_clicked();
protected:
void setupShortcuts();
void saveShortcuts();
};
#endif

@ -1,62 +0,0 @@
#ifndef QTERMINALAPP_H
#define QTERMINALAPP_H
#include <QApplication>
#ifdef HAVE_QDBUS
#include <QtDBus/QtDBus>
#endif
#include "mainwindow.h"
class QTerminalApp : public QApplication
{
Q_OBJECT
public:
MainWindow *newWindow(bool dropMode, TerminalConfig &cfg);
QList<MainWindow*> getWindowList();
void addWindow(MainWindow *window);
void removeWindow(MainWindow *window);
static QTerminalApp *Instance(int &argc, char **argv);
static QTerminalApp *Instance();
QString &getWorkingDirectory();
void setWorkingDirectory(const QString &wd);
#ifdef HAVE_QDBUS
void registerOnDbus();
QList<QDBusObjectPath> getWindows();
QDBusObjectPath newWindow(const QHash<QString,QVariant> &termArgs);
QDBusObjectPath getActiveWindow();
bool isDropMode();
bool toggleDropdown();
#endif
static void cleanup();
private:
QString m_workDir;
QList<MainWindow *> m_windowList;
static QTerminalApp *m_instance;
QTerminalApp(int &argc, char **argv);
~QTerminalApp(){};
};
template <class T> T* findParent(QObject *child)
{
QObject *maybeT = child;
while (true)
{
if (maybeT == NULL)
{
return NULL;
}
T *holder = qobject_cast<T*>(maybeT);
if (holder)
return holder;
maybeT = maybeT->parent();
}
}
#endif

@ -1,68 +0,0 @@
/***************************************************************************
* Copyright (C) 2017 by Nathan Osman *
* nathan@quickmediasolutions.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include "tabbar.h"
TabBar::TabBar(QWidget *parent)
: QTabBar(parent),
mLimitWidth(false),
mLimitWidthValue(0)
{
// To make the selected tab text bold, first give a bold font to the tabbar
// for QStyle::sizeFromContents(QStyle::CT_TabBarTab, ...) to make room
// for the bold text, and then, set the non-selected tab text to normal.
QFont f = font();
f.setBold(true);
setFont(f);
setStyleSheet("QTabBar::tab:!selected { font-weight: normal; }");
}
void TabBar::setLimitWidth(bool limitWidth)
{
mLimitWidth = limitWidth;
}
void TabBar::setLimitWidthValue(int value)
{
mLimitWidthValue = value;
}
void TabBar::updateWidth()
{
// This seems to be the only way to trigger an update
setIconSize(iconSize());
setElideMode(Qt::ElideMiddle);
}
QSize TabBar::tabSizeHint(int index) const
{
QSize size = QTabBar::tabSizeHint(index);
// If the width is limited, use that for the width hint
if (mLimitWidth) {
if (shape() == QTabBar::RoundedEast || shape() == QTabBar::TriangularEast
|| shape() == QTabBar::RoundedWest || shape() == QTabBar::TriangularWest) {
size.setHeight(mLimitWidthValue);
}
else {
size.setWidth(mLimitWidthValue);
}
}
return size;
}

@ -1,47 +0,0 @@
/***************************************************************************
* Copyright (C) 2017 by Nathan Osman *
* nathan@quickmediasolutions.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef TABBAR_H
#define TABBAR_H
#include <QSize>
#include <QTabBar>
class TabBar : public QTabBar
{
Q_OBJECT
public:
explicit TabBar(QWidget *parent);
void setLimitWidth(bool limitWidth);
void setLimitWidthValue(int value);
void updateWidth();
protected:
virtual QSize tabSizeHint(int index) const;
private:
bool mLimitWidth;
int mLimitWidthValue;
};
#endif // TABBAR_H

@ -1,511 +0,0 @@
/***************************************************************************
* Copyright (C) 2006 by Vladimir Kuznetsov *
* vovanec@gmail.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include <QTabBar>
#include <QInputDialog>
#include <QColorDialog>
#include <QMouseEvent>
#include <QMenu>
#include "mainwindow.h"
#include "termwidgetholder.h"
#include "tabbar.h"
#include "tabwidget.h"
#include "config.h"
#include "properties.h"
#include "qterminalapp.h"
#define TAB_INDEX_PROPERTY "tab_index"
#define TAB_CUSTOM_NAME_PROPERTY "custom_name"
TabWidget::TabWidget(QWidget* parent) : QTabWidget(parent), tabNumerator(0), mTabBar(new TabBar(this))
{
// Insert our own tab bar which overrides tab width and eliding
setTabBar(mTabBar);
setFocusPolicy(Qt::NoFocus);
/* On Mac OS X this will look similar to
* the tabs in Safari or Leopard's Terminal.app .
* I love this!
*/
setDocumentMode(true);
tabBar()->setUsesScrollButtons(true);
setMovable(true);
setUsesScrollButtons(true);
tabBar()->installEventFilter(this);
connect(this, &TabWidget::tabCloseRequested, this, &TabWidget::removeTab);
connect(tabBar(), &QTabBar::tabMoved, this, &TabWidget::updateTabIndices);
connect(this, &TabWidget::tabRenameRequested, this, &TabWidget::renameSession);
connect(this, &TabWidget::tabTitleColorChangeRequested, this, &TabWidget::setTitleColor);
}
TermWidgetHolder * TabWidget::terminalHolder()
{
return reinterpret_cast<TermWidgetHolder*>(widget(currentIndex()));
}
int TabWidget::addNewTab(TerminalConfig config)
{
tabNumerator++;
QString label = QString(tr("Shell No. %1")).arg(tabNumerator);
TermWidgetHolder *ch = terminalHolder();
if (ch)
config.provideCurrentDirectory(ch->currentTerminal()->impl()->workingDirectory());
TermWidgetHolder *console = new TermWidgetHolder(config, this);
console->setWindowTitle(label);
connect(console, &TermWidgetHolder::finished, this, &TabWidget::removeFinished);
connect(console, &TermWidgetHolder::lastTerminalClosed, this, &TabWidget::removeFinished);
connect(console, &TermWidgetHolder::termTitleChanged, this, &TabWidget::onTermTitleChanged);
connect(this, &QTabWidget::currentChanged, this, &TabWidget::currentTitleChanged);
int index = addTab(console, label);
console->setProperty(TAB_CUSTOM_NAME_PROPERTY, false);
updateTabIndices();
setCurrentIndex(index);
console->setInitialFocus();
showHideTabBar();
return index;
}
void TabWidget::switchLeftSubterminal()
{
terminalHolder()->directionalNavigation(NavigationDirection::Left);
}
void TabWidget::switchRightSubterminal()
{
terminalHolder()->directionalNavigation(NavigationDirection::Right);
}
void TabWidget::switchTopSubterminal() {
terminalHolder()->directionalNavigation(NavigationDirection::Top);
}
void TabWidget::switchBottomSubterminal() {
terminalHolder()->directionalNavigation(NavigationDirection::Bottom);
}
void TabWidget::splitHorizontally()
{
terminalHolder()->splitHorizontal(terminalHolder()->currentTerminal());
findParent<MainWindow>(this)->updateDisabledActions();
}
void TabWidget::splitVertically()
{
terminalHolder()->splitVertical(terminalHolder()->currentTerminal());
findParent<MainWindow>(this)->updateDisabledActions();
}
void TabWidget::splitCollapse()
{
terminalHolder()->splitCollapse(terminalHolder()->currentTerminal());
findParent<MainWindow>(this)->updateDisabledActions();
}
void TabWidget::copySelection()
{
terminalHolder()->currentTerminal()->impl()->copyClipboard();
}
void TabWidget::pasteClipboard()
{
terminalHolder()->currentTerminal()->impl()->pasteClipboard();
}
void TabWidget::pasteSelection()
{
terminalHolder()->currentTerminal()->impl()->pasteSelection();
}
void TabWidget::zoomIn()
{
terminalHolder()->currentTerminal()->impl()->zoomIn();
}
void TabWidget::zoomOut()
{
terminalHolder()->currentTerminal()->impl()->zoomOut();
}
void TabWidget::zoomReset()
{
terminalHolder()->currentTerminal()->impl()->zoomReset();
}
void TabWidget::updateTabIndices()
{
for(int i = 0; i < count(); i++)
widget(i)->setProperty(TAB_INDEX_PROPERTY, i);
}
void TabWidget::onTermTitleChanged(QString title, QString icon)
{
TermWidgetHolder * console = qobject_cast<TermWidgetHolder*>(sender());
const bool custom_name = console->property(TAB_CUSTOM_NAME_PROPERTY).toBool();
if (!custom_name)
{
const int index = console->property(TAB_INDEX_PROPERTY).toInt();
setTabIcon(index, QIcon::fromTheme(icon));
setTabText(index, title);
if (currentIndex() == index)
emit currentTitleChanged(index);
}
}
void TabWidget::renameSession(int index)
{
bool ok = false;
QString text = QInputDialog::getText(this, tr("Tab name"),
tr("New tab name:"), QLineEdit::Normal,
QString(), &ok);
if(ok && !text.isEmpty())
{
setTabIcon(index, QIcon{});
setTabText(index, text);
widget(index)->setProperty(TAB_CUSTOM_NAME_PROPERTY, true);
if (currentIndex() == index)
emit currentTitleChanged(index);
}
}
void TabWidget::renameCurrentSession()
{
renameSession(currentIndex());
}
void TabWidget::setTitleColor(int index)
{
QColor current = tabBar()->tabTextColor(index);
QColor color = QColorDialog::getColor(current, this, tr("Select new tab title color"));
if (color.isValid())
tabBar()->setTabTextColor(index, color);
}
void TabWidget::renameTabsAfterRemove()
{
// it breaks custom names - it replaces original/custom title with shell no #
#if 0
for(int i = 0; i < count(); i++) {
setTabText(i, QString(tr("Shell No. %1")).arg(i+1));
}
#endif
}
void TabWidget::contextMenuEvent(QContextMenuEvent *event)
{
QMenu menu(this);
QMap< QString, QAction * > actions = findParent<MainWindow>(this)->leaseActions();
QAction *close = menu.addAction(QIcon::fromTheme("document-close"), tr("Close session"));
QAction *rename = menu.addAction(actions[RENAME_SESSION]->text());
QAction *changeColor = menu.addAction(QIcon::fromTheme("color-management"), tr("Change title color"));
rename->setShortcut(actions[RENAME_SESSION]->shortcut());
rename->blockSignals(true);
int tabIndex = tabBar()->tabAt(tabBar()->mapFrom(this,event->pos()));
QAction *action = menu.exec(event->globalPos());
if (action == close) {
emit tabCloseRequested(tabIndex);
} else if (action == rename) {
emit tabRenameRequested(tabIndex);
} else if (action == changeColor) {
emit tabTitleColorChangeRequested(tabIndex);
}
}
bool TabWidget::eventFilter(QObject *obj, QEvent *event)
{
QMouseEvent *e = reinterpret_cast<QMouseEvent*>(event);
if (e->button() == Qt::MidButton) {
if (event->type() == QEvent::MouseButtonRelease) {
// close the tab on middle clicking
int index = tabBar()->tabAt(e->pos());
if (index > -1){
removeTab(index);
return true;
}
}
}
else if (event->type() == QEvent::MouseButtonDblClick)
{
// if user doubleclicks on tab button - rename it. If user
// clicks on free space - open new tab
int index = tabBar()->tabAt(e->pos());
if (index == -1)
{
TerminalConfig defaultConfig;
addNewTab(defaultConfig);
}
else
renameSession(index);
return true;
}
return QTabWidget::eventFilter(obj, event);
}
void TabWidget::removeFinished()
{
QObject* term = sender();
QVariant prop = term->property(TAB_INDEX_PROPERTY);
if(prop.isValid() && prop.canConvert(QVariant::Int))
{
int index = prop.toInt();
removeTab(index);
// if (count() == 0)
// emit closeTabNotification();
}
}
void TabWidget::removeTab(int index)
{
if (count() > 1) {
setUpdatesEnabled(false);
QWidget * w = widget(index);
QTabWidget::removeTab(index);
w->deleteLater();
updateTabIndices();
int current = currentIndex();
if (current >= 0 )
{
qobject_cast<TermWidgetHolder*>(widget(current))->setInitialFocus();
}
// do not decrease it as renaming is disabled in renameTabsAfterRemove
// tabNumerator--;
setUpdatesEnabled(true);
} else {
emit closeTabNotification(true);
}
renameTabsAfterRemove();
showHideTabBar();
}
void TabWidget::removeCurrentTab()
{
// question disabled due user requests. Yes I agree it was anoying.
// if (QMessageBox::question(this,
// tr("Close current session"),
// tr("Are you sure you want to close current sesstion?"),
// QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)
// {
if (count() > 1) {
removeTab(currentIndex());
} else {
emit closeTabNotification(false);
}
}
int TabWidget::switchToRight()
{
int next_pos = currentIndex() + 1;
if (next_pos < count())
setCurrentIndex(next_pos);
else
setCurrentIndex(0);
findParent<MainWindow>(this)->updateDisabledActions();
return currentIndex();
}
int TabWidget::switchToLeft()
{
int previous_pos = currentIndex() - 1;
if (previous_pos < 0)
setCurrentIndex(count() - 1);
else
setCurrentIndex(previous_pos);
findParent<MainWindow>(this)->updateDisabledActions();
return currentIndex();
}
void TabWidget::move(Direction dir)
{
if(count() > 1)
{
int index = currentIndex();
QWidget* child = widget(index);
QString label = tabText(index);
QString toolTip = tabToolTip(index);
QIcon icon = tabIcon(index);
int newIndex = 0;
if(dir == Left)
if(index == 0)
newIndex = count() -1;
else
newIndex = index - 1;
else
if(index == count() - 1)
newIndex = 0;
else
newIndex = index + 1;
setUpdatesEnabled(false);
QTabWidget::removeTab(index);
newIndex = insertTab(newIndex, child, label);
setTabToolTip(newIndex, toolTip);
setTabIcon(newIndex, icon);
setUpdatesEnabled(true);
setCurrentIndex(newIndex);
child->setFocus();
updateTabIndices();
}
}
void TabWidget::moveLeft()
{
move(Left);
}
void TabWidget::moveRight()
{
move(Right);
}
void TabWidget::changeScrollPosition(QAction *triggered)
{
QActionGroup *scrollPosition = static_cast<QActionGroup *>(sender());
if(!scrollPosition)
qFatal("scrollPosition is NULL");
Properties::Instance()->scrollBarPos =
scrollPosition->actions().indexOf(triggered);
Properties::Instance()->saveSettings();
propertiesChanged();
}
void TabWidget::changeTabPosition(QAction *triggered)
{
QActionGroup *tabPosition = static_cast<QActionGroup *>(sender());
if(!tabPosition)
qFatal("tabPosition is NULL");
Properties *prop = Properties::Instance();
/* order is dictated from mainwindow.cpp */
QTabWidget::TabPosition position = (QTabWidget::TabPosition)tabPosition->actions().indexOf(triggered);
setTabPosition(position);
prop->tabsPos = position;
prop->saveSettings();
}
void TabWidget::changeKeyboardCursorShape(QAction *triggered)
{
QActionGroup *keyboardCursorShape = static_cast<QActionGroup *>(sender());
if(!keyboardCursorShape)
qFatal("keyboardCursorShape is NULL");
Properties::Instance()->keyboardCursorShape =
keyboardCursorShape->actions().indexOf(triggered);
Properties::Instance()->saveSettings();
propertiesChanged();
}
void TabWidget::propertiesChanged()
{
for (int i = 0; i < count(); ++i)
{
TermWidgetHolder *console = static_cast<TermWidgetHolder*>(widget(i));
console->propertiesChanged();
}
showHideTabBar();
setTabsClosable(Properties::Instance()->showCloseTabButton);
// Update the tab widths
mTabBar->setLimitWidth(Properties::Instance()->limitTabWidth);
mTabBar->setLimitWidthValue(Properties::Instance()->limitTabWidthValue);
mTabBar->updateWidth();
}
void TabWidget::clearActiveTerminal()
{
reinterpret_cast<TermWidgetHolder*>(widget(currentIndex()))->clearActiveTerminal();
}
void TabWidget::saveSession()
{
int ix = currentIndex();
reinterpret_cast<TermWidgetHolder*>(widget(ix))->saveSession(tabText(ix));
}
void TabWidget::loadSession()
{
reinterpret_cast<TermWidgetHolder*>(widget(currentIndex()))->loadSession();
}
void TabWidget::preset2Horizontal()
{
TerminalConfig defaultConfig;
int ix = TabWidget::addNewTab(defaultConfig);
TermWidgetHolder* term = reinterpret_cast<TermWidgetHolder*>(widget(ix));
term->splitHorizontal(term->currentTerminal());
// switch to the 1st terminal
term->directionalNavigation(NavigationDirection::Left);
}
void TabWidget::preset2Vertical()
{
TerminalConfig defaultConfig;
int ix = TabWidget::addNewTab(defaultConfig);
TermWidgetHolder* term = reinterpret_cast<TermWidgetHolder*>(widget(ix));
term->splitVertical(term->currentTerminal());
// switch to the 1st terminal
term->directionalNavigation(NavigationDirection::Left);
}
void TabWidget::preset4Terminals()
{
TerminalConfig defaultConfig;
int ix = TabWidget::addNewTab(defaultConfig);
TermWidgetHolder* term = reinterpret_cast<TermWidgetHolder*>(widget(ix));
term->splitVertical(term->currentTerminal());
term->splitHorizontal(term->currentTerminal());
term->directionalNavigation(NavigationDirection::Left);
term->splitHorizontal(term->currentTerminal());
// switch to the 1st terminal
term->directionalNavigation(NavigationDirection::Top);
}
void TabWidget::showHideTabBar()
{
if (Properties::Instance()->tabBarless)
tabBar()->setVisible(false);
else
tabBar()->setVisible(!Properties::Instance()->hideTabBarWithOneTab || count() > 1);
}

@ -1,121 +0,0 @@
/***************************************************************************
* Copyright (C) 2006 by Vladimir Kuznetsov *
* vovanec@gmail.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef TAB_WIDGET
#define TAB_WIDGET
#include <QTabWidget>
#include <QMap>
#include <QAction>
#ifdef HAVE_QDBUS
#include <QtDBus/QtDBus>
#include "dbusaddressable.h"
#endif
#include "terminalconfig.h"
#include "properties.h"
class TabBar;
class TermWidgetHolder;
class QAction;
class QActionGroup;
class TabWidget : public QTabWidget
{
Q_OBJECT
public:
TabWidget(QWidget* parent = 0);
TermWidgetHolder * terminalHolder();
void showHideTabBar();
public slots:
int addNewTab(TerminalConfig cfg);
void removeTab(int);
void removeCurrentTab();
int switchToRight();
int switchToLeft();
void removeFinished();
void moveLeft();
void moveRight();
void renameSession(int);
void renameCurrentSession();
void setTitleColor(int);
void switchLeftSubterminal();
void switchRightSubterminal();
void switchTopSubterminal();
void switchBottomSubterminal();
void splitHorizontally();
void splitVertically();
void splitCollapse();
void copySelection();
void pasteClipboard();
void pasteSelection();
void zoomIn();
void zoomOut();
void zoomReset();
void changeTabPosition(QAction *);
void changeScrollPosition(QAction *);
void changeKeyboardCursorShape(QAction *);
void propertiesChanged();
void clearActiveTerminal();
void saveSession();
void loadSession();
void preset2Horizontal();
void preset2Vertical();
void preset4Terminals();
signals:
void closeTabNotification(bool);
void tabRenameRequested(int);
void tabTitleColorChangeRequested(int);
void currentTitleChanged(int);
protected:
enum Direction{Left = 1, Right};
void contextMenuEvent(QContextMenuEvent * event);
void move(Direction);
/*! Event filter for TabWidget's QTabBar. It's installed on tabBar()
in the constructor.
It's purpose is to handle doubleclicks on QTabBar for session
renaming or new tab opening
*/
bool eventFilter(QObject *obj, QEvent *event);
protected slots:
void updateTabIndices();
void onTermTitleChanged(QString title, QString icon);
private:
int tabNumerator;
/* re-order naming of the tabs then removeCurrentTab() */
void renameTabsAfterRemove();
TabBar *mTabBar;
};
#endif

@ -1,105 +0,0 @@
#include <QHash>
#include <QString>
#include "qterminalapp.h"
#include "terminalconfig.h"
#include "properties.h"
#include "termwidget.h"
TerminalConfig::TerminalConfig(const QString & wdir, const QString & shell)
{
m_workingDirectory = wdir;
m_shell = shell;
}
TerminalConfig::TerminalConfig()
{
}
TerminalConfig::TerminalConfig(const TerminalConfig &cfg)
: m_currentDirectory(cfg.m_currentDirectory),
m_workingDirectory(cfg.m_workingDirectory),
m_shell(cfg.m_shell) {}
QString TerminalConfig::getWorkingDirectory()
{
if (!m_workingDirectory.isEmpty())
return m_workingDirectory;
if (Properties::Instance()->useCWD && !m_currentDirectory.isEmpty())
return m_currentDirectory;
return QTerminalApp::Instance()->getWorkingDirectory();
}
QString TerminalConfig::getShell()
{
if (!m_shell.isEmpty())
return m_shell;
if (!Properties::Instance()->shell.isEmpty())
return Properties::Instance()->shell;
QByteArray envShell = qgetenv("SHELL");
if (envShell.constData() != NULL)
{
QString shellString = QString(envShell);
if (!shellString.isEmpty())
return shellString;
}
return QString();
}
void TerminalConfig::setWorkingDirectory(const QString &val)
{
m_workingDirectory = val;
}
void TerminalConfig::setShell(const QString &val)
{
m_shell = val;
}
void TerminalConfig::provideCurrentDirectory(const QString &val)
{
m_currentDirectory = val;
}
#if HAVE_QDBUS
#define DBUS_ARG_WORKDIR "workingDirectory"
#define DBUS_ARG_SHELL "shell"
TerminalConfig TerminalConfig::fromDbus(const QHash<QString,QVariant> &termArgsConst, TermWidget *toSplit)
{
QHash<QString,QVariant> termArgs(termArgsConst);
if (toSplit != NULL && !termArgs.contains(DBUS_ARG_WORKDIR))
{
termArgs[DBUS_ARG_WORKDIR] = QVariant(toSplit->impl()->workingDirectory());
}
return TerminalConfig::fromDbus(termArgs);
}
static QString variantToString(QVariant variant, QString &defaultVal)
{
if (variant.type() == QVariant::String)
return qvariant_cast<QString>(variant);
return defaultVal;
}
TerminalConfig TerminalConfig::fromDbus(const QHash<QString,QVariant> &termArgs)
{
QString wdir("");
QString shell(Properties::Instance()->shell);
if (termArgs.contains(DBUS_ARG_WORKDIR))
{
wdir = variantToString(termArgs[DBUS_ARG_WORKDIR], wdir);
}
if (termArgs.contains(DBUS_ARG_SHELL)) {
shell = variantToString(termArgs[DBUS_ARG_SHELL], shell);
}
return TerminalConfig(wdir, shell);
}
#endif

@ -1,38 +0,0 @@
#ifndef TERMINALCONFIG_H
#define TERMINALCONFIG_H
#include <QHash>
#include <QString>
#include <QVariant>
class TermWidget;
class TerminalConfig
{
public:
TerminalConfig(const QString & wdir, const QString & shell);
TerminalConfig(const TerminalConfig &cfg);
TerminalConfig();
QString getWorkingDirectory();
QString getShell();
void setWorkingDirectory(const QString &val);
void setShell(const QString &val);
void provideCurrentDirectory(const QString &val);
#ifdef HAVE_QDBUS
static TerminalConfig fromDbus(const QHash<QString,QVariant> &termArgs);
static TerminalConfig fromDbus(const QHash<QString,QVariant> &termArgs, TermWidget *toSplit);
#endif
private:
// True when
QString m_currentDirectory;
QString m_workingDirectory;
QString m_shell;
};
#endif

@ -1,378 +0,0 @@
/***************************************************************************
* Copyright (C) 2010 by Petr Vanek *
* petr@scribus.info *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include <QMenu>
#include <QVBoxLayout>
#include <QPainter>
#include <QDesktopServices>
#include <QMessageBox>
#include <QAbstractButton>
#include <QMouseEvent>
#include <assert.h>
#ifdef HAVE_QDBUS
#include <QtDBus/QtDBus>
#include "termwidgetholder.h"
#include "terminaladaptor.h"
#endif
#include "mainwindow.h"
#include "termwidget.h"
#include "config.h"
#include "properties.h"
#include "qterminalapp.h"
static int TermWidgetCount = 0;
TermWidgetImpl::TermWidgetImpl(TerminalConfig &cfg, QWidget * parent)
: QTermWidget(0, parent)
{
TermWidgetCount++;
QString name("TermWidget_%1");
setObjectName(name.arg(TermWidgetCount));
setFlowControlEnabled(FLOW_CONTROL_ENABLED);
setFlowControlWarningEnabled(FLOW_CONTROL_WARNING_ENABLED);
propertiesChanged();
setHistorySize(5000);
setWorkingDirectory(cfg.getWorkingDirectory());
QString shell = cfg.getShell();
if (!shell.isEmpty())
{
qDebug() << "Shell program:" << shell;
QStringList parts = shell.split(QRegExp("\\s+"), QString::SkipEmptyParts);
qDebug() << parts;
setShellProgram(parts.at(0));
parts.removeAt(0);
if (parts.count())
setArgs(parts);
}
setMotionAfterPasting(Properties::Instance()->m_motionAfterPaste);
setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, &QWidget::customContextMenuRequested,
this, &TermWidgetImpl::customContextMenuCall);
connect(this, &QTermWidget::urlActivated, this, &TermWidgetImpl::activateUrl);
startShellProgram();
}
void TermWidgetImpl::propertiesChanged()
{
setColorScheme(Properties::Instance()->colorScheme);
setTerminalFont(Properties::Instance()->font);
setMotionAfterPasting(Properties::Instance()->m_motionAfterPaste);
setTerminalSizeHint(Properties::Instance()->showTerminalSizeHint);
if (Properties::Instance()->historyLimited)
{
setHistorySize(Properties::Instance()->historyLimitedTo);
}
else
{
// Unlimited history
setHistorySize(-1);
}
setKeyBindings(Properties::Instance()->emulation);
setTerminalOpacity(1.0 - Properties::Instance()->termTransparency/100.0);
setTerminalBackgroundImage(Properties::Instance()->backgroundImage);
setBidiEnabled(Properties::Instance()->enabledBidiSupport);
/* be consequent with qtermwidget.h here */
switch(Properties::Instance()->scrollBarPos) {
case 0:
setScrollBarPosition(QTermWidget::NoScrollBar);
break;
case 1:
setScrollBarPosition(QTermWidget::ScrollBarLeft);
break;
case 2:
default:
setScrollBarPosition(QTermWidget::ScrollBarRight);
break;
}
switch(Properties::Instance()->keyboardCursorShape) {
case 1:
setKeyboardCursorShape(QTermWidget::KeyboardCursorShape::UnderlineCursor);
break;
case 2:
setKeyboardCursorShape(QTermWidget::KeyboardCursorShape::IBeamCursor);
break;
default:
case 0:
setKeyboardCursorShape(QTermWidget::KeyboardCursorShape::BlockCursor);
break;
}
update();
}
void TermWidgetImpl::customContextMenuCall(const QPoint & pos)
{
QMenu menu;
QMap<QString, QAction*> actions = findParent<MainWindow>(this)->leaseActions();
QList<QAction*> extraActions = filterActions(pos);
for (auto& action : extraActions)
{
menu.addAction(action);
}
if (!actions.isEmpty())
{
menu.addSeparator();
}
menu.addAction(actions[COPY_SELECTION]);
menu.addAction(actions[PASTE_CLIPBOARD]);
menu.addAction(actions[PASTE_SELECTION]);
menu.addAction(actions[ZOOM_IN]);
menu.addAction(actions[ZOOM_OUT]);
menu.addAction(actions[ZOOM_RESET]);
menu.addSeparator();
menu.addAction(actions[CLEAR_TERMINAL]);
menu.addAction(actions[SPLIT_HORIZONTAL]);
menu.addAction(actions[SPLIT_VERTICAL]);
// warning TODO/FIXME: disable the action when there is only one terminal
menu.addAction(actions[SUB_COLLAPSE]);
menu.addSeparator();
menu.addAction(actions[TOGGLE_MENU]);
menu.addAction(actions[PREFERENCES]);
menu.exec(mapToGlobal(pos));
}
void TermWidgetImpl::zoomIn()
{
emit QTermWidget::zoomIn();
// note: do not save zoom here due the #74 Zoom reset option resets font back to Monospace
// Properties::Instance()->font = getTerminalFont();
// Properties::Instance()->saveSettings();
}
void TermWidgetImpl::zoomOut()
{
emit QTermWidget::zoomOut();
// note: do not save zoom here due the #74 Zoom reset option resets font back to Monospace
// Properties::Instance()->font = getTerminalFont();
// Properties::Instance()->saveSettings();
}
void TermWidgetImpl::zoomReset()
{
// note: do not save zoom here due the #74 Zoom reset option resets font back to Monospace
// Properties::Instance()->font = Properties::Instance()->font;
setTerminalFont(Properties::Instance()->font);
// Properties::Instance()->saveSettings();
}
void TermWidgetImpl::activateUrl(const QUrl & url, bool fromContextMenu) {
if (QApplication::keyboardModifiers() & Qt::ControlModifier || fromContextMenu) {
QDesktopServices::openUrl(url);
}
}
void TermWidgetImpl::pasteSelection()
{
paste(QClipboard::Selection);
}
void TermWidgetImpl::pasteClipboard()
{
paste(QClipboard::Clipboard);
}
void TermWidgetImpl::paste(QClipboard::Mode mode)
{
// Paste Clipboard by simulating keypress events
QString text = QApplication::clipboard()->text(mode);
if ( ! text.isEmpty() )
{
text.replace("\r\n", "\n");
text.replace('\n', '\r');
QString trimmedTrailingNl(text);
trimmedTrailingNl.replace(QRegExp("\\r+$"), "");
bool isMultiline = trimmedTrailingNl.contains('\r');
if (!isMultiline && Properties::Instance()->trimPastedTrailingNewlines)
{
text = trimmedTrailingNl;
}
if (Properties::Instance()->confirmMultilinePaste)
{
if (text.contains('\r') && Properties::Instance()->confirmMultilinePaste)
{
QMessageBox confirmation(this);
confirmation.setWindowTitle(tr("Paste multiline text"));
confirmation.setText(tr("Are you sure you want to paste this text?"));
confirmation.setDetailedText(text);
confirmation.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
// Click "Show details..." to show those by default
const auto buttons = confirmation.buttons();
for( QAbstractButton * btn : buttons )
{
if (confirmation.buttonRole(btn) == QMessageBox::ActionRole && btn->text() == QMessageBox::tr("Show Details..."))
{
btn->clicked();
break;
}
}
confirmation.setDefaultButton(QMessageBox::Yes);
confirmation.exec();
if (confirmation.standardButton(confirmation.clickedButton()) != QMessageBox::Yes)
{
return;
}
}
}
bracketText(text);
sendText(text);
}
}
bool TermWidget::eventFilter(QObject * obj, QEvent * ev)
{
if (ev->type() == QEvent::MouseButtonPress)
{
QMouseEvent *mev = (QMouseEvent *)ev;
if ( mev->button() == Qt::MidButton )
{
impl()->pasteSelection();
return true;
}
}
return false;
}
TermWidget::TermWidget(TerminalConfig &cfg, QWidget * parent)
: QWidget(parent),
DBusAddressable("/terminals")
{
#ifdef HAVE_QDBUS
registerAdapter<TerminalAdaptor, TermWidget>(this);
#endif
m_border = palette().color(QPalette::Window);
m_term = new TermWidgetImpl(cfg, this);
setFocusProxy(m_term);
m_layout = new QVBoxLayout;
setLayout(m_layout);
m_layout->addWidget(m_term);
const auto objs = m_term->children();
for (QObject *o : objs)
{
// Find TerminalDisplay
if (!o->isWidgetType() || qobject_cast<QWidget*>(o)->isHidden())
continue;
o->installEventFilter(this);
}
propertiesChanged();
connect(m_term, &QTermWidget::finished, this, &TermWidget::finished);
connect(m_term, &QTermWidget::termGetFocus, this, &TermWidget::term_termGetFocus);
connect(m_term, &QTermWidget::termLostFocus, this, &TermWidget::term_termLostFocus);
connect(m_term, &QTermWidget::titleChanged, this, [this] { emit termTitleChanged(m_term->title(), m_term->icon()); });
}
void TermWidget::propertiesChanged()
{
if (Properties::Instance()->highlightCurrentTerminal)
m_layout->setContentsMargins(2, 2, 2, 2);
else
m_layout->setContentsMargins(0, 0, 0, 0);
m_term->propertiesChanged();
}
void TermWidget::term_termGetFocus()
{
m_border = palette().color(QPalette::Highlight);
emit termGetFocus(this);
update();
}
void TermWidget::term_termLostFocus()
{
m_border = palette().color(QPalette::Window);
update();
}
void TermWidget::paintEvent (QPaintEvent *)
{
if (Properties::Instance()->highlightCurrentTerminal)
{
QPainter p(this);
QPen pen(m_border);
pen.setWidth(3);
pen.setBrush(m_border);
p.setPen(pen);
p.drawRect(0, 0, width()-1, height()-1);
}
}
#if HAVE_QDBUS
QDBusObjectPath TermWidget::splitHorizontal(const QHash<QString,QVariant> &termArgs)
{
TermWidgetHolder *holder = findParent<TermWidgetHolder>(this);
assert(holder != NULL);
TerminalConfig cfg = TerminalConfig::fromDbus(termArgs, this);
return holder->split(this, Qt::Horizontal, cfg)->getDbusPath();
}
QDBusObjectPath TermWidget::splitVertical(const QHash<QString,QVariant> &termArgs)
{
TermWidgetHolder *holder = findParent<TermWidgetHolder>(this);
assert(holder != NULL);
TerminalConfig cfg = TerminalConfig::fromDbus(termArgs, this);
return holder->split(this, Qt::Vertical, cfg)->getDbusPath();
}
QDBusObjectPath TermWidget::getTab()
{
return findParent<TermWidgetHolder>(this)->getDbusPath();
}
void TermWidget::closeTerminal()
{
TermWidgetHolder *holder = findParent<TermWidgetHolder>(this);
holder->splitCollapse(this);
}
void TermWidget::sendText(const QString text)
{
if (impl())
{
impl()->sendText(text);
}
}
#endif

@ -1,104 +0,0 @@
/***************************************************************************
* Copyright (C) 2010 by Petr Vanek *
* petr@scribus.info *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef TERMWIDGET_H
#define TERMWIDGET_H
#include <qtermwidget.h>
#include "terminalconfig.h"
#include <QClipboard>
#include <QAction>
#include "dbusaddressable.h"
class TermWidgetImpl : public QTermWidget
{
Q_OBJECT
// QMap< QString, QAction * > actionMap;
public:
TermWidgetImpl(TerminalConfig &cfg, QWidget * parent=0);
void propertiesChanged();
void paste(QClipboard::Mode mode);
signals:
void renameSession();
void removeCurrentSession();
public slots:
void zoomIn();
void zoomOut();
void zoomReset();
void pasteSelection();
void pasteClipboard();
private slots:
void customContextMenuCall(const QPoint & pos);
void activateUrl(const QUrl& url, bool fromContextMenu);
};
class TermWidget : public QWidget, public DBusAddressable
{
Q_OBJECT
TermWidgetImpl * m_term;
QVBoxLayout * m_layout;
QColor m_border;
public:
TermWidget(TerminalConfig &cfg, QWidget * parent=0);
void propertiesChanged();
QStringList availableKeyBindings() { return m_term->availableKeyBindings(); }
TermWidgetImpl * impl() { return m_term; }
#ifdef HAVE_QDBUS
QDBusObjectPath splitHorizontal(const QHash<QString,QVariant> &termArgs);
QDBusObjectPath splitVertical(const QHash<QString,QVariant> &termArgs);
QDBusObjectPath getTab();
void sendText(const QString text);
void closeTerminal();
#endif
signals:
void finished();
void renameSession();
void removeCurrentSession();
void splitHorizontal(TermWidget * self);
void splitVertical(TermWidget * self);
void splitCollapse(TermWidget * self);
void termGetFocus(TermWidget * self);
void termTitleChanged(QString titleText, QString icon);
public slots:
protected:
void paintEvent (QPaintEvent * event);
bool eventFilter(QObject * obj, QEvent * evt) override;
private slots:
void term_termGetFocus();
void term_termLostFocus();
};
#endif

@ -1,449 +0,0 @@
/***************************************************************************
* Copyright (C) 2010 by Petr Vanek *
* petr@scribus.info *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include <QGridLayout>
#include <QSplitter>
#include <QInputDialog>
#ifdef HAVE_QDBUS
#include <QtDBus/QtDBus>
#include "tabadaptor.h"
#endif
#include "qterminalapp.h"
#include "mainwindow.h"
#include "termwidgetholder.h"
#include "termwidget.h"
#include "properties.h"
#include <assert.h>
#include <climits>
#include <algorithm>
TermWidgetHolder::TermWidgetHolder(TerminalConfig &config, QWidget * parent)
: QWidget(parent)
#ifdef HAVE_QDBUS
, DBusAddressable("/tabs")
#endif
{
#ifdef HAVE_QDBUS
new TabAdaptor(this);
QDBusConnection::sessionBus().registerObject(getDbusPathString(), this);
#endif
setFocusPolicy(Qt::NoFocus);
QGridLayout * lay = new QGridLayout(this);
lay->setSpacing(0);
lay->setContentsMargins(0, 0, 0, 0);
QSplitter *s = new QSplitter(this);
s->setFocusPolicy(Qt::NoFocus);
TermWidget *w = newTerm(config);
s->addWidget(w);
lay->addWidget(s);
m_currentTerm = w;
setLayout(lay);
}
TermWidgetHolder::~TermWidgetHolder()
{
}
void TermWidgetHolder::setInitialFocus()
{
QList<TermWidget*> list = findChildren<TermWidget*>();
TermWidget * w = list.count() == 0 ? 0 : list.at(0);
if (w)
w->setFocus(Qt::OtherFocusReason);
}
void TermWidgetHolder::loadSession()
{
bool ok;
QString name = QInputDialog::getItem(this, tr("Load Session"),
tr("List of saved sessions:"),
Properties::Instance()->sessions.keys(),
0, false, &ok);
if (!ok || name.isEmpty())
return;
#if 0
foreach (QWidget * w, findChildren<QWidget*>())
{
if (w)
{
delete w;
w = 0;
}
}
qDebug() << "load" << name << QString(Properties::Instance()->sessions[name]);
QStringList splitters = QString(Properties::Instance()->sessions[name]).split("|", QString::SkipEmptyParts);
foreach (QString splitter, splitters)
{
QStringList components = splitter.split(",");
qDebug() << "comp" << components;
// orientation
Qt::Orientation orientation;
if (components.size() > 0)
orientation = components.takeAt(0).toInt();
// sizes
QList<int> sizes;
QList<TermWidget*> widgets;
foreach (QString s, components)
{
sizes << s.toInt();
widgets << newTerm();
}
// new terms
}
#endif
}
void TermWidgetHolder::saveSession(const QString & name)
{
Session dump;
QString num("%1");
const auto ws = findChildren<QSplitter*>();
for(QSplitter *w : ws)
{
dump += '|' + num.arg(w->orientation());
const auto sizes = w->sizes();
for (const int i : sizes)
dump += ',' + num.arg(i);
}
Properties::Instance()->sessions[name] = dump;
qDebug() << "dump" << dump;
}
TermWidget* TermWidgetHolder::currentTerminal()
{
return m_currentTerm;
}
void TermWidgetHolder::setWDir(const QString & wdir)
{
m_wdir = wdir;
}
typedef struct {
QPoint topLeft;
QPoint middle;
QPoint bottomRight;
} NavigationData;
static void transpose(QPoint *point) {
int x = point->x();
point->setX(point->y());
point->setY(x);
}
static void transposeTransform(NavigationData *point) {
transpose(&point->topLeft);
transpose(&point->middle);
transpose(&point->bottomRight);
}
static void flipTransform(NavigationData *point) {
QPoint oldTopLeft = point->topLeft;
point->topLeft = -(point->bottomRight);
point->bottomRight = -(oldTopLeft);
point->middle = -(point->middle);
}
static void normalizeToRight(NavigationData *point, NavigationDirection dir) {
switch (dir) {
case Left:
flipTransform(point);
break;
case Right:
// No-op
break;
case Top:
flipTransform(point);
transposeTransform(point);
break;
case Bottom:
transposeTransform(point);
break;
default:
assert("Invalid navigation");
return;
}
}
static NavigationData getNormalizedDimensions(QWidget *w, NavigationDirection dir) {
NavigationData nd;
nd.topLeft = w->mapTo(w->window(), QPoint(0, 0));
nd.middle = w->mapTo(w->window(), QPoint(w->width() / 2, w->height() / 2));
nd.bottomRight = w->mapTo(w->window(), QPoint(w->width(), w->height()));
normalizeToRight(&nd, dir);
return nd;
}
void TermWidgetHolder::directionalNavigation(NavigationDirection dir) {
// Find an active widget
QList<TermWidget*> l = findChildren<TermWidget*>();
int ix = -1;
for (TermWidget * w : qAsConst(l))
{
++ix;
if (w->impl()->hasFocus())
{
break;
}
}
if (ix > l.count())
{
l.at(0)->impl()->setFocus(Qt::OtherFocusReason);
return;
}
// Found an active widget
TermWidget *w = l.at(ix);
NavigationData from = getNormalizedDimensions(w, dir);
// Search parent that contains point of interest (right edge middlepoint)
QPoint poi = QPoint(from.bottomRight.x(), from.middle.y());
// Perform a search for a TermWidget, where x() is strictly higher than
// poi.x(), y() is strictly less than poi.y(), and prioritizing, in order,
// lower x(), and lower distance between poi.y() and corners.
// Only "Right navigation" implementation is necessary -- other cases
// are normalized to this one.
l = findChildren<TermWidget*>();
int lowestX = INT_MAX;
int lowestMidpointDistance = INT_MAX;
TermWidget *fittest = NULL;
for (TermWidget * w : qAsConst(l))
{
NavigationData contenderDims = getNormalizedDimensions(w, dir);
int midpointDistance = std::min(
abs(poi.y() - contenderDims.topLeft.y()),
abs(poi.y() - contenderDims.bottomRight.y())
);
if (contenderDims.topLeft.x() > poi.x())
{
if (contenderDims.topLeft.x() > lowestX)
continue;
if (midpointDistance > lowestMidpointDistance)
continue;
lowestX = contenderDims.topLeft.x();
lowestMidpointDistance = midpointDistance;
fittest = w;
}
}
if (fittest != NULL) {
fittest->impl()->setFocus(Qt::OtherFocusReason);
}
}
void TermWidgetHolder::clearActiveTerminal()
{
currentTerminal()->impl()->clear();
}
void TermWidgetHolder::propertiesChanged()
{
const auto ws = findChildren<TermWidget*>();
for(TermWidget *w : ws)
w->propertiesChanged();
}
void TermWidgetHolder::splitHorizontal(TermWidget * term)
{
TerminalConfig defaultConfig;
split(term, Qt::Vertical, defaultConfig);
}
void TermWidgetHolder::splitVertical(TermWidget * term)
{
TerminalConfig defaultConfig;
split(term, Qt::Horizontal, defaultConfig);
}
void TermWidgetHolder::splitCollapse(TermWidget * term)
{
QSplitter * parent = qobject_cast<QSplitter*>(term->parent());
assert(parent);
term->setParent(0);
delete term;
QWidget *nextFocus = Q_NULLPTR;
// Collapse splitters containing a single element, excluding the top one.
if (parent->count() == 1)
{
QSplitter *uselessSplitterParent = qobject_cast<QSplitter*>(parent->parent());
if (uselessSplitterParent != Q_NULLPTR) {
int idx = uselessSplitterParent->indexOf(parent);
assert(idx != -1);
QWidget *singleHeir = parent->widget(0);
uselessSplitterParent->insertWidget(idx, singleHeir);
if (qobject_cast<TermWidget*>(singleHeir))
{
nextFocus = singleHeir;
}
else
{
nextFocus = singleHeir->findChild<TermWidget*>();
}
parent->setParent(0);
delete parent;
// Make sure there's no access to the removed parent
parent = uselessSplitterParent;
}
}
if (parent->count() > 0)
{
if (nextFocus)
{
nextFocus->setFocus(Qt::OtherFocusReason);
}
else
{
parent->widget(0)->setFocus(Qt::OtherFocusReason);
}
parent->update();
}
else
emit finished();
}
TermWidget * TermWidgetHolder::split(TermWidget *term, Qt::Orientation orientation, TerminalConfig cfg)
{
QSplitter *parent = qobject_cast<QSplitter *>(term->parent());
assert(parent);
int ix = parent->indexOf(term);
QList<int> parentSizes = parent->sizes();
QList<int> sizes;
sizes << 1 << 1;
QSplitter *s = new QSplitter(orientation, this);
s->setFocusPolicy(Qt::NoFocus);
s->insertWidget(0, term);
cfg.provideCurrentDirectory(term->impl()->workingDirectory());
TermWidget * w = newTerm(cfg);
s->insertWidget(1, w);
s->setSizes(sizes);
parent->insertWidget(ix, s);
parent->setSizes(parentSizes);
w->setFocus(Qt::OtherFocusReason);
return w;
}
TermWidget *TermWidgetHolder::newTerm(TerminalConfig &cfg)
{
TermWidget *w = new TermWidget(cfg, this);
// proxy signals
connect(w, &TermWidget::renameSession, this, &TermWidgetHolder::renameSession);
connect(w, &TermWidget::removeCurrentSession, this, &TermWidgetHolder::lastTerminalClosed);
connect(w, &TermWidget::finished, this, &TermWidgetHolder::handle_finished);
// consume signals
connect(w, static_cast<void (TermWidget::*)(TermWidget *self)>(&TermWidget::splitHorizontal),
this, &TermWidgetHolder::splitHorizontal);
connect(w, static_cast<void (TermWidget::*)(TermWidget *self)>(&TermWidget::splitVertical),
this, &TermWidgetHolder::splitVertical);
connect(w, &TermWidget::splitCollapse, this, &TermWidgetHolder::splitCollapse);
connect(w, &TermWidget::termGetFocus, this, &TermWidgetHolder::setCurrentTerminal);
connect(w, &TermWidget::termTitleChanged, this, &TermWidgetHolder::onTermTitleChanged);
return w;
}
void TermWidgetHolder::setCurrentTerminal(TermWidget* term)
{
TermWidget * old_current = m_currentTerm;
m_currentTerm = term;
if (old_current != m_currentTerm)
{
if (m_currentTerm->impl()->isTitleChanged())
{
emit termTitleChanged(m_currentTerm->impl()->title(), m_currentTerm->impl()->icon());
} else
{
emit termTitleChanged(windowTitle(), QString{});
}
}
}
void TermWidgetHolder::handle_finished()
{
TermWidget * w = qobject_cast<TermWidget*>(sender());
if (!w)
{
qDebug() << "TermWidgetHolder::handle_finished: Unknown object to handle" << w;
assert(0);
}
splitCollapse(w);
}
void TermWidgetHolder::onTermTitleChanged(QString title, QString icon) const
{
TermWidget * term = qobject_cast<TermWidget *>(sender());
if (m_currentTerm == term)
emit termTitleChanged(title, icon);
}
#ifdef HAVE_QDBUS
QDBusObjectPath TermWidgetHolder::getActiveTerminal()
{
if (m_currentTerm != NULL)
{
return m_currentTerm->getDbusPath();
}
return QDBusObjectPath();
}
QList<QDBusObjectPath> TermWidgetHolder::getTerminals()
{
QList<QDBusObjectPath> terminals;
const auto ws = findChildren<TermWidget*>();
for (TermWidget* w : ws)
{
terminals.push_back(w->getDbusPath());
}
return terminals;
}
QDBusObjectPath TermWidgetHolder::getWindow()
{
return findParent<MainWindow>(this)->getDbusPath();
}
void TermWidgetHolder::closeTab()
{
QTabWidget *parent = findParent<QTabWidget>(this);
int idx = parent->indexOf(this);
assert(idx != -1);
parent->tabCloseRequested(idx);
}
#endif

@ -1,105 +0,0 @@
/***************************************************************************
* Copyright (C) 2010 by Petr Vanek *
* petr@scribus.info *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef TERMWIDGETHOLDER_H
#define TERMWIDGETHOLDER_H
#include <QWidget>
#include "termwidget.h"
#include "terminalconfig.h"
#include "dbusaddressable.h"
class QSplitter;
typedef enum NavigationDirection {
Left,
Right,
Top,
Bottom
} NavigationDirection;
/*! \brief TermWidget group/session manager.
This widget (one per TabWidget tab) is a "proxy" widget beetween TabWidget and
unspecified count of TermWidgets. Basically it should look like a single TermWidget
for TabWidget - with its signals and slots.
Splitting and collapsing of TermWidgets is done here.
*/
class TermWidgetHolder : public QWidget
#ifdef HAVE_QDBUS
, public DBusAddressable
#endif
{
Q_OBJECT
public:
TermWidgetHolder(TerminalConfig &cfg, QWidget * parent=0);
~TermWidgetHolder();
void propertiesChanged();
void setInitialFocus();
void loadSession();
void saveSession(const QString & name);
void zoomIn(uint step);
void zoomOut(uint step);
TermWidget* currentTerminal();
TermWidget* split(TermWidget * term, Qt::Orientation orientation, TerminalConfig cfg);
#ifdef HAVE_QDBUS
QDBusObjectPath getActiveTerminal();
QList<QDBusObjectPath> getTerminals();
QDBusObjectPath getWindow();
void closeTab();
#endif
public slots:
void splitHorizontal(TermWidget * term);
void splitVertical(TermWidget * term);
void splitCollapse(TermWidget * term);
void setWDir(const QString & wdir);
void directionalNavigation(NavigationDirection dir);
void clearActiveTerminal();
void onTermTitleChanged(QString title, QString icon) const;
signals:
void finished();
void lastTerminalClosed();
void renameSession();
void termTitleChanged(QString title, QString icon) const;
private:
QString m_wdir;
QString m_shell;
TermWidget * m_currentTerm;
void split(TermWidget * term, Qt::Orientation orientation);
TermWidget * newTerm(TerminalConfig &cfg);
private slots:
void setCurrentTerminal(TermWidget* term);
void handle_finished();
};
#endif

@ -1,233 +0,0 @@
/****************************************************************************
** Copyright (c) 2006 - 2011, the LibQxt project.
** See the Qxt AUTHORS file for a list of authors and copyright holders.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** * Neither the name of the LibQxt project nor the
** names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** <http://libqxt.org> <foundation@libqxt.org>
*****************************************************************************/
#ifndef QXTGLOBAL_H
#define QXTGLOBAL_H
#include <QtGlobal>
#define QXT_VERSION 0x000700
#define QXT_VERSION_STR "0.7.0"
//--------------------------global macros------------------------------
#ifndef QXT_NO_MACROS
#ifndef _countof
#define _countof(x) (sizeof(x)/sizeof(*x))
#endif
#endif // QXT_NO_MACROS
//--------------------------export macros------------------------------
#define QXT_DLLEXPORT DO_NOT_USE_THIS_ANYMORE
#if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN)
# if defined(BUILD_QXT_CORE)
# define QXT_CORE_EXPORT Q_DECL_EXPORT
# else
# define QXT_CORE_EXPORT Q_DECL_IMPORT
# endif
#else
# define QXT_CORE_EXPORT
#endif // BUILD_QXT_CORE
#if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN)
# if defined(BUILD_QXT_GUI)
# define QXT_GUI_EXPORT Q_DECL_EXPORT
# else
# define QXT_GUI_EXPORT Q_DECL_IMPORT
# endif
#else
# define QXT_GUI_EXPORT
#endif // BUILD_QXT_GUI
#if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN)
# if defined(BUILD_QXT_NETWORK)
# define QXT_NETWORK_EXPORT Q_DECL_EXPORT
# else
# define QXT_NETWORK_EXPORT Q_DECL_IMPORT
# endif
#else
# define QXT_NETWORK_EXPORT
#endif // BUILD_QXT_NETWORK
#if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN)
# if defined(BUILD_QXT_SQL)
# define QXT_SQL_EXPORT Q_DECL_EXPORT
# else
# define QXT_SQL_EXPORT Q_DECL_IMPORT
# endif
#else
# define QXT_SQL_EXPORT
#endif // BUILD_QXT_SQL
#if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN)
# if defined(BUILD_QXT_WEB)
# define QXT_WEB_EXPORT Q_DECL_EXPORT
# else
# define QXT_WEB_EXPORT Q_DECL_IMPORT
# endif
#else
# define QXT_WEB_EXPORT
#endif // BUILD_QXT_WEB
#if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN)
# if defined(BUILD_QXT_BERKELEY)
# define QXT_BERKELEY_EXPORT Q_DECL_EXPORT
# else
# define QXT_BERKELEY_EXPORT Q_DECL_IMPORT
# endif
#else
# define QXT_BERKELEY_EXPORT
#endif // BUILD_QXT_BERKELEY
#if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN)
# if defined(BUILD_QXT_ZEROCONF)
# define QXT_ZEROCONF_EXPORT Q_DECL_EXPORT
# else
# define QXT_ZEROCONF_EXPORT Q_DECL_IMPORT
# endif
#else
# define QXT_ZEROCONF_EXPORT
#endif // QXT_ZEROCONF_EXPORT
#if defined(BUILD_QXT_CORE) || defined(BUILD_QXT_GUI) || defined(BUILD_QXT_SQL) || defined(BUILD_QXT_NETWORK) || defined(BUILD_QXT_WEB) || defined(BUILD_QXT_BERKELEY) || defined(BUILD_QXT_ZEROCONF)
# define BUILD_QXT
#endif
QXT_CORE_EXPORT const char* qxtVersion();
#ifndef QT_BEGIN_NAMESPACE
#define QT_BEGIN_NAMESPACE
#endif
#ifndef QT_END_NAMESPACE
#define QT_END_NAMESPACE
#endif
#ifndef QT_FORWARD_DECLARE_CLASS
#define QT_FORWARD_DECLARE_CLASS(Class) class Class;
#endif
/****************************************************************************
** This file is derived from code bearing the following notice:
** The sole author of this file, Adam Higerd, has explicitly disclaimed all
** copyright interest and protection for the content within. This file has
** been placed in the public domain according to United States copyright
** statute and case law. In jurisdictions where this public domain dedication
** is not legally recognized, anyone who receives a copy of this file is
** permitted to use, modify, duplicate, and redistribute this file, in whole
** or in part, with no restrictions or conditions. In these jurisdictions,
** this file shall be copyright (C) 2006-2008 by Adam Higerd.
****************************************************************************/
#define QXT_DECLARE_PRIVATE(PUB) friend class PUB##Private; QxtPrivateInterface<PUB, PUB##Private> qxt_d;
#define QXT_DECLARE_PUBLIC(PUB) friend class PUB;
#define QXT_INIT_PRIVATE(PUB) qxt_d.setPublic(this);
#define QXT_D(PUB) PUB##Private& d = qxt_d()
#define QXT_P(PUB) PUB& p = qxt_p()
template <typename PUB>
class QxtPrivate
{
public:
virtual ~QxtPrivate()
{}
inline void QXT_setPublic(PUB* pub)
{
qxt_p_ptr = pub;
}
protected:
inline PUB& qxt_p()
{
return *qxt_p_ptr;
}
inline const PUB& qxt_p() const
{
return *qxt_p_ptr;
}
inline PUB* qxt_ptr()
{
return qxt_p_ptr;
}
inline const PUB* qxt_ptr() const
{
return qxt_p_ptr;
}
private:
PUB* qxt_p_ptr;
};
template <typename PUB, typename PVT>
class QxtPrivateInterface
{
friend class QxtPrivate<PUB>;
public:
QxtPrivateInterface()
{
pvt = new PVT;
}
~QxtPrivateInterface()
{
delete pvt;
}
inline void setPublic(PUB* pub)
{
pvt->QXT_setPublic(pub);
}
inline PVT& operator()()
{
return *static_cast<PVT*>(pvt);
}
inline const PVT& operator()() const
{
return *static_cast<PVT*>(pvt);
}
inline PVT * operator->()
{
return static_cast<PVT*>(pvt);
}
inline const PVT * operator->() const
{
return static_cast<PVT*>(pvt);
}
private:
QxtPrivateInterface(const QxtPrivateInterface&) { }
QxtPrivateInterface& operator=(const QxtPrivateInterface&) { }
QxtPrivate<PUB>* pvt;
};
#endif // QXT_GLOBAL

@ -1,212 +0,0 @@
#include "qxtglobalshortcut.h"
/****************************************************************************
** Copyright (c) 2006 - 2011, the LibQxt project.
** See the Qxt AUTHORS file for a list of authors and copyright holders.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** * Neither the name of the LibQxt project nor the
** names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** <http://libqxt.org> <foundation@libqxt.org>
*****************************************************************************/
#include "qxtglobalshortcut_p.h"
#include <QAbstractEventDispatcher>
#include <QtDebug>
#ifndef Q_OS_MAC
int QxtGlobalShortcutPrivate::ref = 0;
#endif
QHash<QPair<quint32, quint32>, QxtGlobalShortcut*> QxtGlobalShortcutPrivate::shortcuts;
QxtGlobalShortcutPrivate::QxtGlobalShortcutPrivate() : enabled(true), key(Qt::Key(0)), mods(Qt::NoModifier)
{
#ifndef Q_OS_MAC
if (ref == 0) {
QAbstractEventDispatcher::instance()->installNativeEventFilter(this);
}
++ref;
#endif
}
QxtGlobalShortcutPrivate::~QxtGlobalShortcutPrivate()
{
#ifndef Q_OS_MAC
--ref;
if (ref == 0) {
QAbstractEventDispatcher *ed = QAbstractEventDispatcher::instance();
if (ed != 0) {
ed->removeNativeEventFilter(this);
}
}
#endif
}
bool QxtGlobalShortcutPrivate::setShortcut(const QKeySequence& shortcut)
{
Qt::KeyboardModifiers allMods = Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier;
key = shortcut.isEmpty() ? Qt::Key(0) : Qt::Key((shortcut[0] ^ allMods) & shortcut[0]);
mods = shortcut.isEmpty() ? Qt::KeyboardModifiers(0) : Qt::KeyboardModifiers(shortcut[0] & allMods);
const quint32 nativeKey = nativeKeycode(key);
const quint32 nativeMods = nativeModifiers(mods);
const bool res = registerShortcut(nativeKey, nativeMods);
if (res)
shortcuts.insert(qMakePair(nativeKey, nativeMods), &qxt_p());
else
qWarning() << "QxtGlobalShortcut failed to register:" << QKeySequence(key + mods).toString();
return res;
}
bool QxtGlobalShortcutPrivate::unsetShortcut()
{
bool res = false;
const quint32 nativeKey = nativeKeycode(key);
const quint32 nativeMods = nativeModifiers(mods);
if (shortcuts.value(qMakePair(nativeKey, nativeMods)) == &qxt_p())
res = unregisterShortcut(nativeKey, nativeMods);
if (res)
shortcuts.remove(qMakePair(nativeKey, nativeMods));
else
qWarning() << "QxtGlobalShortcut failed to unregister:" << QKeySequence(key + mods).toString();
key = Qt::Key(0);
mods = Qt::KeyboardModifiers(0);
return res;
}
void QxtGlobalShortcutPrivate::activateShortcut(quint32 nativeKey, quint32 nativeMods)
{
QxtGlobalShortcut* shortcut = shortcuts.value(qMakePair(nativeKey, nativeMods));
if (shortcut && shortcut->isEnabled())
emit shortcut->activated();
}
/*!
\class QxtGlobalShortcut
\inmodule QxtWidgets
\brief The QxtGlobalShortcut class provides a global shortcut aka "hotkey".
A global shortcut triggers even if the application is not active. This
makes it easy to implement applications that react to certain shortcuts
still if some other application is active or if the application is for
example minimized to the system tray.
Example usage:
\code
QxtGlobalShortcut* shortcut = new QxtGlobalShortcut(window);
connect(shortcut, SIGNAL(activated()), window, SLOT(toggleVisibility()));
shortcut->setShortcut(QKeySequence("Ctrl+Shift+F12"));
\endcode
\bold {Note:} Since Qxt 0.6 QxtGlobalShortcut no more requires QxtApplication.
*/
/*!
\fn QxtGlobalShortcut::activated()
This signal is emitted when the user types the shortcut's key sequence.
\sa shortcut
*/
/*!
Constructs a new QxtGlobalShortcut with \a parent.
*/
QxtGlobalShortcut::QxtGlobalShortcut(QObject* parent)
: QObject(parent)
{
QXT_INIT_PRIVATE(QxtGlobalShortcut);
}
/*!
Constructs a new QxtGlobalShortcut with \a shortcut and \a parent.
*/
QxtGlobalShortcut::QxtGlobalShortcut(const QKeySequence& shortcut, QObject* parent)
: QObject(parent)
{
QXT_INIT_PRIVATE(QxtGlobalShortcut);
setShortcut(shortcut);
}
/*!
Destructs the QxtGlobalShortcut.
*/
QxtGlobalShortcut::~QxtGlobalShortcut()
{
if (qxt_d().key != 0)
qxt_d().unsetShortcut();
}
/*!
\property QxtGlobalShortcut::shortcut
\brief the shortcut key sequence
\bold {Note:} Notice that corresponding key press and release events are not
delivered for registered global shortcuts even if they are disabled.
Also, comma separated key sequences are not supported.
Only the first part is used:
\code
qxtShortcut->setShortcut(QKeySequence("Ctrl+Alt+A,Ctrl+Alt+B"));
Q_ASSERT(qxtShortcut->shortcut() == QKeySequence("Ctrl+Alt+A"));
\endcode
*/
QKeySequence QxtGlobalShortcut::shortcut() const
{
return QKeySequence(qxt_d().key | qxt_d().mods);
}
bool QxtGlobalShortcut::setShortcut(const QKeySequence& shortcut)
{
if (qxt_d().key != 0)
qxt_d().unsetShortcut();
return qxt_d().setShortcut(shortcut);
}
/*!
\property QxtGlobalShortcut::enabled
\brief whether the shortcut is enabled
A disabled shortcut does not get activated.
The default value is \c true.
\sa setDisabled()
*/
bool QxtGlobalShortcut::isEnabled() const
{
return qxt_d().enabled;
}
void QxtGlobalShortcut::setEnabled(bool enabled)
{
qxt_d().enabled = enabled;
}
/*!
Sets the shortcut \a disabled.
\sa enabled
*/
void QxtGlobalShortcut::setDisabled(bool disabled)
{
qxt_d().enabled = !disabled;
}

@ -1,64 +0,0 @@
#ifndef QXTGLOBALSHORTCUT_H
/****************************************************************************
** Copyright (c) 2006 - 2011, the LibQxt project.
** See the Qxt AUTHORS file for a list of authors and copyright holders.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** * Neither the name of the LibQxt project nor the
** names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** <http://libqxt.org> <foundation@libqxt.org>
*****************************************************************************/
#define QXTGLOBALSHORTCUT_H
#include "qxtglobal.h"
#include <QObject>
#include <QKeySequence>
class QxtGlobalShortcutPrivate;
class QXT_GUI_EXPORT QxtGlobalShortcut : public QObject
{
Q_OBJECT
QXT_DECLARE_PRIVATE(QxtGlobalShortcut)
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut)
public:
explicit QxtGlobalShortcut(QObject* parent = 0);
explicit QxtGlobalShortcut(const QKeySequence& shortcut, QObject* parent = 0);
virtual ~QxtGlobalShortcut();
QKeySequence shortcut() const;
bool setShortcut(const QKeySequence& shortcut);
bool isEnabled() const;
public Q_SLOTS:
void setEnabled(bool enabled = true);
void setDisabled(bool disabled = true);
Q_SIGNALS:
void activated();
};
#endif // QXTGLOBALSHORTCUT_H

@ -1,258 +0,0 @@
#include <Carbon/Carbon.h>
/****************************************************************************
** Copyright (c) 2006 - 2011, the LibQxt project.
** See the Qxt AUTHORS file for a list of authors and copyright holders.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** * Neither the name of the LibQxt project nor the
** names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** <http://libqxt.org> <foundation@libqxt.org>
*****************************************************************************/
#include "qxtglobalshortcut_p.h"
#include <QMap>
#include <QHash>
#include <QtDebug>
#include <QApplication>
typedef QPair<uint, uint> Identifier;
static QMap<quint32, EventHotKeyRef> keyRefs;
static QHash<Identifier, quint32> keyIDs;
static quint32 hotKeySerial = 0;
static bool qxt_mac_handler_installed = false;
OSStatus qxt_mac_handle_hot_key(EventHandlerCallRef nextHandler, EventRef event, void* data)
{
Q_UNUSED(nextHandler);
Q_UNUSED(data);
if (GetEventClass(event) == kEventClassKeyboard && GetEventKind(event) == kEventHotKeyPressed)
{
EventHotKeyID keyID;
GetEventParameter(event, kEventParamDirectObject, typeEventHotKeyID, NULL, sizeof(keyID), NULL, &keyID);
Identifier id = keyIDs.key(keyID.id);
QxtGlobalShortcutPrivate::activateShortcut(id.second, id.first);
}
return noErr;
}
quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers)
{
quint32 native = 0;
if (modifiers & Qt::ShiftModifier)
native |= shiftKey;
if (modifiers & Qt::ControlModifier)
native |= cmdKey;
if (modifiers & Qt::AltModifier)
native |= optionKey;
if (modifiers & Qt::MetaModifier)
native |= controlKey;
if (modifiers & Qt::KeypadModifier)
native |= kEventKeyModifierNumLockMask;
return native;
}
quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key)
{
UTF16Char ch;
// Constants found in NSEvent.h from AppKit.framework
switch (key)
{
case Qt::Key_Return:
return kVK_Return;
case Qt::Key_Enter:
return kVK_ANSI_KeypadEnter;
case Qt::Key_Tab:
return kVK_Tab;
case Qt::Key_Space:
return kVK_Space;
case Qt::Key_Backspace:
return kVK_Delete;
case Qt::Key_Control:
return kVK_Command;
case Qt::Key_Shift:
return kVK_Shift;
case Qt::Key_CapsLock:
return kVK_CapsLock;
case Qt::Key_Option:
return kVK_Option;
case Qt::Key_Meta:
return kVK_Control;
case Qt::Key_F17:
return kVK_F17;
case Qt::Key_VolumeUp:
return kVK_VolumeUp;
case Qt::Key_VolumeDown:
return kVK_VolumeDown;
case Qt::Key_F18:
return kVK_F18;
case Qt::Key_F19:
return kVK_F19;
case Qt::Key_F20:
return kVK_F20;
case Qt::Key_F5:
return kVK_F5;
case Qt::Key_F6:
return kVK_F6;
case Qt::Key_F7:
return kVK_F7;
case Qt::Key_F3:
return kVK_F3;
case Qt::Key_F8:
return kVK_F8;
case Qt::Key_F9:
return kVK_F9;
case Qt::Key_F11:
return kVK_F11;
case Qt::Key_F13:
return kVK_F13;
case Qt::Key_F16:
return kVK_F16;
case Qt::Key_F14:
return kVK_F14;
case Qt::Key_F10:
return kVK_F10;
case Qt::Key_F12:
return kVK_F12;
case Qt::Key_F15:
return kVK_F15;
case Qt::Key_Help:
return kVK_Help;
case Qt::Key_Home:
return kVK_Home;
case Qt::Key_PageUp:
return kVK_PageUp;
case Qt::Key_Delete:
return kVK_ForwardDelete;
case Qt::Key_F4:
return kVK_F4;
case Qt::Key_End:
return kVK_End;
case Qt::Key_F2:
return kVK_F2;
case Qt::Key_PageDown:
return kVK_PageDown;
case Qt::Key_F1:
return kVK_F1;
case Qt::Key_Left:
return kVK_LeftArrow;
case Qt::Key_Right:
return kVK_RightArrow;
case Qt::Key_Down:
return kVK_DownArrow;
case Qt::Key_Up:
return kVK_UpArrow;
default:
;
}
if (key == Qt::Key_Escape) ch = 27;
else if (key == Qt::Key_Return) ch = 13;
else if (key == Qt::Key_Enter) ch = 3;
else if (key == Qt::Key_Tab) ch = 9;
else ch = key;
CFDataRef currentLayoutData;
TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
if (currentKeyboard == NULL)
return 0;
currentLayoutData = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData);
CFRelease(currentKeyboard);
if (currentLayoutData == NULL)
return 0;
UCKeyboardLayout* header = (UCKeyboardLayout*)CFDataGetBytePtr(currentLayoutData);
UCKeyboardTypeHeader* table = header->keyboardTypeList;
uint8_t *data = (uint8_t*)header;
// God, would a little documentation for this shit kill you...
for (quint32 i=0; i < header->keyboardTypeCount; i++)
{
UCKeyStateRecordsIndex* stateRec = 0;
if (table[i].keyStateRecordsIndexOffset != 0)
{
stateRec = reinterpret_cast<UCKeyStateRecordsIndex*>(data + table[i].keyStateRecordsIndexOffset);
if (stateRec->keyStateRecordsIndexFormat != kUCKeyStateRecordsIndexFormat) stateRec = 0;
}
UCKeyToCharTableIndex* charTable = reinterpret_cast<UCKeyToCharTableIndex*>(data + table[i].keyToCharTableIndexOffset);
if (charTable->keyToCharTableIndexFormat != kUCKeyToCharTableIndexFormat) continue;
for (quint32 j=0; j < charTable->keyToCharTableCount; j++)
{
UCKeyOutput* keyToChar = reinterpret_cast<UCKeyOutput*>(data + charTable->keyToCharTableOffsets[j]);
for (quint32 k=0; k < charTable->keyToCharTableSize; k++)
{
if (keyToChar[k] & kUCKeyOutputTestForIndexMask)
{
long idx = keyToChar[k] & kUCKeyOutputGetIndexMask;
if (stateRec && idx < stateRec->keyStateRecordCount)
{
UCKeyStateRecord* rec = reinterpret_cast<UCKeyStateRecord*>(data + stateRec->keyStateRecordOffsets[idx]);
if (rec->stateZeroCharData == ch) return k;
}
}
else if (!(keyToChar[k] & kUCKeyOutputSequenceIndexMask) && keyToChar[k] < 0xFFFE)
{
if (keyToChar[k] == ch) return k;
}
} // for k
} // for j
} // for i
return 0;
}
bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods)
{
if (!qxt_mac_handler_installed)
{
EventTypeSpec t;
t.eventClass = kEventClassKeyboard;
t.eventKind = kEventHotKeyPressed;
InstallApplicationEventHandler(&qxt_mac_handle_hot_key, 1, &t, NULL, NULL);
}
EventHotKeyID keyID;
keyID.signature = 'cute';
keyID.id = ++hotKeySerial;
EventHotKeyRef ref = 0;
bool rv = !RegisterEventHotKey(nativeKey, nativeMods, keyID, GetApplicationEventTarget(), 0, &ref);
if (rv)
{
keyIDs.insert(Identifier(nativeMods, nativeKey), keyID.id);
keyRefs.insert(keyID.id, ref);
}
return rv;
}
bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods)
{
Identifier id(nativeMods, nativeKey);
if (!keyIDs.contains(id)) return false;
EventHotKeyRef ref = keyRefs.take(keyIDs[id]);
keyIDs.remove(id);
return !UnregisterEventHotKey(ref);
}

@ -1,76 +0,0 @@
#ifndef QXTGLOBALSHORTCUT_P_H
/****************************************************************************
** Copyright (c) 2006 - 2011, the LibQxt project.
** See the Qxt AUTHORS file for a list of authors and copyright holders.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** * Neither the name of the LibQxt project nor the
** names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** <http://libqxt.org> <foundation@libqxt.org>
*****************************************************************************/
#define QXTGLOBALSHORTCUT_P_H
#include "qxtglobalshortcut.h"
#include <QAbstractEventDispatcher>
#include <QAbstractNativeEventFilter>
#include <QKeySequence>
#include <QHash>
class QxtGlobalShortcutPrivate : public QxtPrivate<QxtGlobalShortcut>
#if !defined(Q_OS_MAC)
,public QAbstractNativeEventFilter
#endif
{
public:
QXT_DECLARE_PUBLIC(QxtGlobalShortcut)
QxtGlobalShortcutPrivate();
~QxtGlobalShortcutPrivate();
bool enabled;
Qt::Key key;
Qt::KeyboardModifiers mods;
bool setShortcut(const QKeySequence& shortcut);
bool unsetShortcut();
static bool error;
#ifndef Q_OS_MAC
static int ref;
virtual bool nativeEventFilter(const QByteArray & eventType, void * message, long * result);
#endif
static void activateShortcut(quint32 nativeKey, quint32 nativeMods);
private:
static quint32 nativeKeycode(Qt::Key keycode);
static quint32 nativeModifiers(Qt::KeyboardModifiers modifiers);
static bool registerShortcut(quint32 nativeKey, quint32 nativeMods);
static bool unregisterShortcut(quint32 nativeKey, quint32 nativeMods);
static QHash<QPair<quint32, quint32>, QxtGlobalShortcut*> shortcuts;
};
#endif // QXTGLOBALSHORTCUT_P_H

@ -1,243 +0,0 @@
#include "qxtglobalshortcut_p.h"
/****************************************************************************
** Copyright (c) 2006 - 2011, the LibQxt project.
** See the Qxt AUTHORS file for a list of authors and copyright holders.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** * Neither the name of the LibQxt project nor the
** names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** <http://libqxt.org> <foundation@libqxt.org>
*****************************************************************************/
#include <qt_windows.h>
bool QxtGlobalShortcutPrivate::nativeEventFilter(const QByteArray & eventType,
void * message, long * result)
{
Q_UNUSED(eventType);
Q_UNUSED(result);
MSG* msg = static_cast<MSG*>(message);
if (msg->message == WM_HOTKEY)
{
const quint32 keycode = HIWORD(msg->lParam);
const quint32 modifiers = LOWORD(msg->lParam);
activateShortcut(keycode, modifiers);
}
return false;
}
quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers)
{
// MOD_ALT, MOD_CONTROL, (MOD_KEYUP), MOD_SHIFT, MOD_WIN
quint32 native = 0;
if (modifiers & Qt::ShiftModifier)
native |= MOD_SHIFT;
if (modifiers & Qt::ControlModifier)
native |= MOD_CONTROL;
if (modifiers & Qt::AltModifier)
native |= MOD_ALT;
if (modifiers & Qt::MetaModifier)
native |= MOD_WIN;
// TODO: resolve these?
//if (modifiers & Qt::KeypadModifier)
//if (modifiers & Qt::GroupSwitchModifier)
return native;
}
quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key)
{
switch (key)
{
case Qt::Key_Escape:
return VK_ESCAPE;
case Qt::Key_Tab:
case Qt::Key_Backtab:
return VK_TAB;
case Qt::Key_Backspace:
return VK_BACK;
case Qt::Key_Return:
case Qt::Key_Enter:
return VK_RETURN;
case Qt::Key_Insert:
return VK_INSERT;
case Qt::Key_Delete:
return VK_DELETE;
case Qt::Key_Pause:
return VK_PAUSE;
case Qt::Key_Print:
return VK_PRINT;
case Qt::Key_Clear:
return VK_CLEAR;
case Qt::Key_Home:
return VK_HOME;
case Qt::Key_End:
return VK_END;
case Qt::Key_Left:
return VK_LEFT;
case Qt::Key_Up:
return VK_UP;
case Qt::Key_Right:
return VK_RIGHT;
case Qt::Key_Down:
return VK_DOWN;
case Qt::Key_PageUp:
return VK_PRIOR;
case Qt::Key_PageDown:
return VK_NEXT;
case Qt::Key_F1:
return VK_F1;
case Qt::Key_F2:
return VK_F2;
case Qt::Key_F3:
return VK_F3;
case Qt::Key_F4:
return VK_F4;
case Qt::Key_F5:
return VK_F5;
case Qt::Key_F6:
return VK_F6;
case Qt::Key_F7:
return VK_F7;
case Qt::Key_F8:
return VK_F8;
case Qt::Key_F9:
return VK_F9;
case Qt::Key_F10:
return VK_F10;
case Qt::Key_F11:
return VK_F11;
case Qt::Key_F12:
return VK_F12;
case Qt::Key_F13:
return VK_F13;
case Qt::Key_F14:
return VK_F14;
case Qt::Key_F15:
return VK_F15;
case Qt::Key_F16:
return VK_F16;
case Qt::Key_F17:
return VK_F17;
case Qt::Key_F18:
return VK_F18;
case Qt::Key_F19:
return VK_F19;
case Qt::Key_F20:
return VK_F20;
case Qt::Key_F21:
return VK_F21;
case Qt::Key_F22:
return VK_F22;
case Qt::Key_F23:
return VK_F23;
case Qt::Key_F24:
return VK_F24;
case Qt::Key_Space:
return VK_SPACE;
case Qt::Key_Asterisk:
return VK_MULTIPLY;
case Qt::Key_Plus:
return VK_ADD;
case Qt::Key_Comma:
return VK_SEPARATOR;
case Qt::Key_Minus:
return VK_SUBTRACT;
case Qt::Key_Slash:
return VK_DIVIDE;
case Qt::Key_MediaNext:
return VK_MEDIA_NEXT_TRACK;
case Qt::Key_MediaPrevious:
return VK_MEDIA_PREV_TRACK;
case Qt::Key_MediaPlay:
return VK_MEDIA_PLAY_PAUSE;
case Qt::Key_MediaStop:
return VK_MEDIA_STOP;
// couldn't find those in VK_*
//case Qt::Key_MediaLast:
//case Qt::Key_MediaRecord:
case Qt::Key_VolumeDown:
return VK_VOLUME_DOWN;
case Qt::Key_VolumeUp:
return VK_VOLUME_UP;
case Qt::Key_VolumeMute:
return VK_VOLUME_MUTE;
// numbers
case Qt::Key_0:
case Qt::Key_1:
case Qt::Key_2:
case Qt::Key_3:
case Qt::Key_4:
case Qt::Key_5:
case Qt::Key_6:
case Qt::Key_7:
case Qt::Key_8:
case Qt::Key_9:
return key;
// letters
case Qt::Key_A:
case Qt::Key_B:
case Qt::Key_C:
case Qt::Key_D:
case Qt::Key_E:
case Qt::Key_F:
case Qt::Key_G:
case Qt::Key_H:
case Qt::Key_I:
case Qt::Key_J:
case Qt::Key_K:
case Qt::Key_L:
case Qt::Key_M:
case Qt::Key_N:
case Qt::Key_O:
case Qt::Key_P:
case Qt::Key_Q:
case Qt::Key_R:
case Qt::Key_S:
case Qt::Key_T:
case Qt::Key_U:
case Qt::Key_V:
case Qt::Key_W:
case Qt::Key_X:
case Qt::Key_Y:
case Qt::Key_Z:
return key;
default:
return 0;
}
}
bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods)
{
return RegisterHotKey(0, nativeMods ^ nativeKey, nativeMods, nativeKey);
}
bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods)
{
return UnregisterHotKey(0, nativeMods ^ nativeKey);
}

@ -1,224 +0,0 @@
#include "qxtglobalshortcut_p.h"
/****************************************************************************
** Copyright (c) 2006 - 2011, the LibQxt project.
** See the Qxt AUTHORS file for a list of authors and copyright holders.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** * Neither the name of the LibQxt project nor the
** names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** <http://libqxt.org> <foundation@libqxt.org>
*****************************************************************************/
/****************************************************************************
*
* Note: This file is a modified version for QTerminal!
*
****************************************************************************/
#include <QVector>
#include <QtX11Extras/QX11Info>
#include <xcb/xcb.h>
#include <X11/Xlib.h>
namespace {
const QVector<quint32> maskModifiers = QVector<quint32>()
<< 0 << Mod2Mask << LockMask << (Mod2Mask | LockMask);
typedef int (*X11ErrorHandler)(Display *display, XErrorEvent *event);
class QxtX11ErrorHandler {
public:
static bool error;
static int qxtX11ErrorHandler(Display *display, XErrorEvent *event)
{
Q_UNUSED(display);
switch (event->error_code)
{
case BadAccess:
case BadValue:
case BadWindow:
if (event->request_code == 33 /* X_GrabKey */ ||
event->request_code == 34 /* X_UngrabKey */)
{
error = true;
//TODO:
//char errstr[256];
//XGetErrorText(dpy, err->error_code, errstr, 256);
}
}
return 0;
}
QxtX11ErrorHandler()
{
error = false;
m_previousErrorHandler = XSetErrorHandler(qxtX11ErrorHandler);
}
~QxtX11ErrorHandler()
{
XSetErrorHandler(m_previousErrorHandler);
}
private:
X11ErrorHandler m_previousErrorHandler;
};
bool QxtX11ErrorHandler::error = false;
class QxtX11Data {
public:
QxtX11Data()
{
m_display = QX11Info::display();
}
bool isValid()
{
return m_display != 0;
}
Display *display()
{
Q_ASSERT(isValid());
return m_display;
}
Window rootWindow()
{
return DefaultRootWindow(display());
}
bool grabKey(quint32 keycode, quint32 modifiers, Window window)
{
QxtX11ErrorHandler errorHandler;
for (int i = 0; !errorHandler.error && i < maskModifiers.size(); ++i) {
XGrabKey(display(), keycode, modifiers | maskModifiers[i], window, True,
GrabModeAsync, GrabModeAsync);
}
if (errorHandler.error) {
ungrabKey(keycode, modifiers, window);
return false;
}
return true;
}
bool ungrabKey(quint32 keycode, quint32 modifiers, Window window)
{
QxtX11ErrorHandler errorHandler;
for (const quint32& maskMods : qAsConst(maskModifiers)) {
XUngrabKey(display(), keycode, modifiers | maskMods, window);
}
return !errorHandler.error;
}
private:
Display *m_display;
};
} // namespace
bool QxtGlobalShortcutPrivate::nativeEventFilter(const QByteArray & eventType,
void *message, long *result)
{
Q_UNUSED(result);
xcb_key_press_event_t *kev = 0;
if (eventType == "xcb_generic_event_t") {
xcb_generic_event_t *ev = static_cast<xcb_generic_event_t *>(message);
if ((ev->response_type & 127) == XCB_KEY_PRESS)
kev = static_cast<xcb_key_press_event_t *>(message);
}
if (kev != 0) {
unsigned int keycode = kev->detail;
unsigned int keystate = 0;
if(kev->state & XCB_MOD_MASK_1)
keystate |= Mod1Mask;
if(kev->state & XCB_MOD_MASK_CONTROL)
keystate |= ControlMask;
if(kev->state & XCB_MOD_MASK_4)
keystate |= Mod4Mask;
if(kev->state & XCB_MOD_MASK_SHIFT)
keystate |= ShiftMask;
activateShortcut(keycode,
// Mod1Mask == Alt, Mod4Mask == Meta
keystate & (ShiftMask | ControlMask | Mod1Mask | Mod4Mask));
}
return false;
}
quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers)
{
// ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, and Mod5Mask
quint32 native = 0;
if (modifiers & Qt::ShiftModifier)
native |= ShiftMask;
if (modifiers & Qt::ControlModifier)
native |= ControlMask;
if (modifiers & Qt::AltModifier)
native |= Mod1Mask;
if (modifiers & Qt::MetaModifier)
native |= Mod4Mask;
// TODO: resolve these?
//if (modifiers & Qt::MetaModifier)
//if (modifiers & Qt::KeypadModifier)
//if (modifiers & Qt::GroupSwitchModifier)
return native;
}
quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key)
{
QxtX11Data x11;
if (!x11.isValid())
return 0;
KeySym keysym = XStringToKeysym(QKeySequence(key).toString().toLatin1().data());
if (keysym == NoSymbol)
keysym = static_cast<ushort>(key);
return XKeysymToKeycode(x11.display(), keysym);
}
bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods)
{
QxtX11Data x11;
return x11.isValid() && x11.grabKey(nativeKey, nativeMods, x11.rootWindow());
}
bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods)
{
QxtX11Data x11;
return x11.isValid() && x11.ungrabKey(nativeKey, nativeMods, x11.rootWindow());
}
Loading…
Cancel
Save