parent
fecc5ec75d
commit
ed05002b24
@ -1,12 +0,0 @@
|
||||
Upstream Authors:
|
||||
LXQt team: http://lxqt.org
|
||||
Razor team: http://razor-qt.org
|
||||
|
||||
Copyright:
|
||||
Copyright (c) 2010-2012 Razor team
|
||||
Copyright (c) 2012-2017 LXQt team
|
||||
|
||||
License: LGPL-2.1+ and BSD-3-clause
|
||||
The full text of the LGPL-2.1+ licenses can be found in the 'COPYING' file.
|
||||
The full text of the BSD-3-clause license can be found in the headers of
|
||||
the files under this license.
|
@ -1,530 +0,0 @@
|
||||
|
||||
liblxqt-0.12.0 / 2017-10-21
|
||||
===========================
|
||||
|
||||
* Bump minimum qtxdg version to 3.1.0
|
||||
* Don't export github templates
|
||||
* Bump version and needed versions to the final values
|
||||
* lxqtpower: Allow disabling of lxqt-session provider
|
||||
* Drops Qt5Core_VERSION_STRING
|
||||
* HtmlDelegate: Fix sizeHint() computation
|
||||
* Add some comments about the meaning of versions
|
||||
* Move LXQt version back to liblxqt
|
||||
* Fixes (#118)
|
||||
* lxqtapplication: Avoid wrong signal handling
|
||||
* Removes unneeded semicolon in namespace definition
|
||||
* Fix format conversions [-Wformat-pedantic] warnings
|
||||
* Suppress compiler warnings about unused function parameters
|
||||
* Removes extra semicolons in Qt's Q macros
|
||||
* Translator: Prefer XDG_DATA_DIRS over compiled in path
|
||||
* Help the compiler optimizing loops
|
||||
* Use const variables where possible
|
||||
* Update AUTHORS
|
||||
|
||||
0.11.1 / 2017-01-01
|
||||
===================
|
||||
|
||||
* Release 0.11.1: Update changelog
|
||||
* Bump needed build tools version (#113)
|
||||
* build: Enable/disable WITH_XDG_DIRS_FALLBACK based on Qt version (#111)
|
||||
* Updates lxqt-build-tools required version
|
||||
* Adds a CMake minimum version requirement to the -config.cmake
|
||||
* Refactors superbuild support
|
||||
* Adds PROJECT_NAME to the build with Qt version message
|
||||
* Pack target_compile_definitions() and target_include_directories()
|
||||
* Adds PROJECT_NAME to the build with Qt version message
|
||||
* Pack target_compile_definitions() and target_include_directories()
|
||||
* Use the LXQtConfigVars module
|
||||
* Make liblxqt depend on lxqt-build-tools
|
||||
* Use the lxqt-build-tools LXQtCreatePortableHeaders
|
||||
* Use the new LXQt Build Tools package
|
||||
* Sets a minimum Qt5Xdg required version
|
||||
* Adds minimum Qt version requirement (5.4.2)
|
||||
* Remove cpack (#107)
|
||||
|
||||
0.11.0 / 2016-09-24
|
||||
===================
|
||||
|
||||
* Release 0.11.0: Add changelog
|
||||
* Bump version ot 0.11.0 (#105)
|
||||
* Settings: Make use of reverse_iterator conditional
|
||||
* Application: Add <cerrno> include
|
||||
* Settings: Add "homemade" XDG_CONFIG_DIRS support
|
||||
* Settings: unify duplicated code
|
||||
* Add README.md
|
||||
* translations: Change default translations repository
|
||||
* Update DBus Notify method annotation name
|
||||
* Fix lupdate warning missing Q_OBJECT macro
|
||||
* Replaces deprecated QStyleOptionViewItemV4
|
||||
* Don't lock the screen when it's already locked.
|
||||
* lxqtscreensaver: Makes it a opaque pointer class
|
||||
* GridLayout: Store current animation flag
|
||||
* lxqtgridlayout: Move private class definition
|
||||
* HtmlDelegate: Take layoutDirection into account
|
||||
* GridLayout: Take layoutDirection into account
|
||||
* application: Correct signal handling & clean-up (#72)
|
||||
* lxqtpower: Removes unused stuff
|
||||
* SingleApplication: Only create an DBus adaptor when needed
|
||||
* NotificationPrivate: Fixes programming typo
|
||||
* Don't set icon theme name
|
||||
* configdialog: Update icons in ThemeChanged event
|
||||
* lxqtpower: Add suspend and hibernate to ConsoleKit2 provider
|
||||
* LXQtTranslateTs.cmake: Enable PULL_TRANSLATIONS by default
|
||||
* LXQtTranslateTs.cmake: Use/update template in remote repo
|
||||
* .gitignore: Cleanup
|
||||
* build: Use external translations
|
||||
* ts-files removal (#90)
|
||||
* GridLayout: Fix memory leak
|
||||
* translations: Fix external translations logic
|
||||
* translations: Add external translations support
|
||||
* configdialog: Fix icon bar sizing
|
||||
* configdialog: fix size of PageSelectWidget (#83)
|
||||
* Use const references with the foreach iterator
|
||||
* SettingsCache: Improve performance
|
||||
* Print warning messages when using the fallback Icon Theme
|
||||
* Use LXQT_DATA_DIR for fallback icon theme search path
|
||||
* Sets Oxygen as the only fallback icon theme
|
||||
* Adds CMAKE_INSTALL_PREFIX to the LXQt Theme search paths
|
||||
* LXQtCompilerSettings: Add QT_USE_QSTRINGBUILDER to the compile definitions
|
||||
* SingleApplication: Use QCoreApplication::exit() instead of ::exit()
|
||||
* bump year
|
||||
* TranslateDesktopTs: Adds UPDATE_OPTIONS options
|
||||
* TranslateDesktop: Remove lupdate absolute option
|
||||
* TranslateDesktop: Use -a switch in grep commands
|
||||
* LXQtTheme: Remove (outdated) "singleclick" qss assembly
|
||||
* settings: Upgrade emitting of "changed" signals
|
||||
* SingleApplication: Call also QWidget::show on activate
|
||||
* Updated Russian translation Removed ru_RU file
|
||||
* Use QString() instead of ""
|
||||
* Use CMAKE_INSTALL_FULL_DATAROOTDIR
|
||||
* Add LXQT_GRAPHICS_DIR directory definition
|
||||
* lxqt-config: Correct escaping while setting variables
|
||||
* CMake: Removes artifact
|
||||
* Adds FindXdgUserDirs CMake find_package module
|
||||
* Italian translation update
|
||||
|
||||
0.10.0 / 2015-11-02
|
||||
===================
|
||||
|
||||
* Release 0.10.0
|
||||
* Update translations
|
||||
* Fix mixed indents
|
||||
* Fix license file
|
||||
* Revert "Lock screen on suspend and hibernate"
|
||||
* gridlayout: Use linear animation
|
||||
* gridlayout: Add occupied geometry info
|
||||
* gridlayout: Fix setting geometry info
|
||||
* gridlayout: Add animated move support
|
||||
* license fix for AUTHORS
|
||||
* config dialog: Protect against null pages add.
|
||||
* pluginTranslation: removed using QStringLiteral as it was causing SEGFAULT in static finalization time
|
||||
* pluginTranslation: add some symbol for referencing (for file to be not stripped out in static linking time)
|
||||
* Adds "automatic" plugin translations loader support
|
||||
* Warn missing xscreensaver in a non-blocking way
|
||||
* Fix typos in translations/liblxqt_fr_FR.ts
|
||||
* Removed country variant, improved and corrected italian translation
|
||||
* Update lxqtpower.h
|
||||
* Lock screen on suspend and hibernate
|
||||
* licensefix for lxqttranslator.cpp
|
||||
* Fix typos in comments in lxqtsingleapplicatoin.h
|
||||
* Rename LxQt to LXQt everywhere
|
||||
* Update Greek (el) translation Remove country variant in language code
|
||||
* Handles CMake policy CMP0063
|
||||
* Adds an lxqt_enable_target_exceptions() CMake function
|
||||
* Adds LXQtCompilerSettings CMake module
|
||||
* Removes Cannot open qss file
|
||||
* LXQtCreatePkgConfigFile.cmake: Makes install COMPONENT configurable
|
||||
* LXQtTranslateTs.cmake Adds install COMPONENT option
|
||||
* Adds Runtime install COMPONENT
|
||||
* fix build with qt 5.5
|
||||
* Fixes an SuperBuild/NormalBuild FTBFS
|
||||
* CMake: Use CMAKE_AUTOUIC, drop qt5_wrap()
|
||||
* CMake: Quote variables
|
||||
* CMake: Removes unused variables
|
||||
* configdialog: Sets the page layout margin to 0
|
||||
* LxQt::Application: unix signal handling support & (optional) quit handling
|
||||
* Removes LIB_INSTALL_DIR CACHE PATH variable
|
||||
* Removes deprecated documentation
|
||||
* Use relative paths in install DESTINATION
|
||||
* Marks link libraries as PUBLIC
|
||||
* Use target_compile_definitions() instead of add_definitions()
|
||||
* Make Release the default build type
|
||||
* Simplifies build type matching
|
||||
* lxqt-config.cmake.in: Use find_dependency()
|
||||
* Updates the build system to the Targets infrastructure
|
||||
* Removes .tx transaction dir artifact
|
||||
* Sort .desktop translations. Fix typos in the comments. Remove local dir artifact.
|
||||
* Updated template and german translation after moving about dialog.
|
||||
* pkg-config: Adds Qt5Xdg to the required dependencies
|
||||
* Updates lxqt_create_pkgconfig_file()
|
||||
* Remove trailing whitespaces
|
||||
* Stops using Qt5Xdg dropped stuff
|
||||
* Adds LXQT_DATA_DIR configuration variable
|
||||
* Sort screen saver error messages
|
||||
* Updates translations
|
||||
* Moves the about dialog to lxqt-about
|
||||
* debug: showing qDebug()/qWarning() only in "debug" build
|
||||
* LxQtTheme: removed superfluous warning (can't occure)
|
||||
* debug: strip debug messages in "release" build
|
||||
* Remove AddPluginDialog as it is no longer used
|
||||
* Hungarian translation update
|
||||
* Method to change buttons in the buttonbar of ConfigDialog has been added.
|
||||
* gridlayout: avoid array out of bounds for misused sizes configuration
|
||||
* gridlayout: correctly recover from wrong minSize setting
|
||||
* gridlayout: avoid empty margins when stretching is active
|
||||
* lxqtpower: prefer systemd as a power provider
|
||||
* ConfigDialog: allow changing page by QWidget*
|
||||
* Add KDevelop4 project type to .gitignore
|
||||
* addplugindialog: added managing button
|
||||
* require c++11 support
|
||||
* addplugindialog: support for managing plugins
|
||||
* Updated german translation.
|
||||
* addplugindialog: corrected <> -> "" in include
|
||||
* addplugindialog: remember list position
|
||||
* Prepends an '/' to LXQT_RELATIVE_SHARE_TRANSLATIONS_DIR
|
||||
* Removes misleading "Qt translations not found!" warning
|
||||
|
||||
0.9.0 / 2015-02-07
|
||||
==================
|
||||
|
||||
* Release 0.9.0
|
||||
* - Remove KF5 from prefix. This will fix compilation when KDE framework headers are not in standard paths.
|
||||
* Enhance the panel Add Plugin Dialog
|
||||
* Portuguese update
|
||||
* Workaround Qt 5.4 issue: Re-add a config file to the file watcher if it's already deleted to get proper change notifications.
|
||||
* Update Japanese translation.
|
||||
* i18n/i10n: Updates documentation and behavior
|
||||
* remove lxqtleave from liblxqt
|
||||
* lxqt_translate_desktop: pass -h instead of --no-filename to grep which is compatible with Busybox
|
||||
* Add Portuguese for actions .desktop files
|
||||
* add executable to handle leave actions
|
||||
* Revert 34232018eb. Fixes #430.
|
||||
* Update Japanese translation.
|
||||
* lxqt_translate_desktop: Updates code to cope with the cmake-policy CMP0054
|
||||
* german translation
|
||||
* Fix ConsoleKit powerprovicer to handle everything but logout
|
||||
* - Use simple approach to data dir. Current setup of code not allows both qt4 and qt5 cohexists, and data files are same for both libraries. If a different data dir is required for specifics reason, is possible to set in cmake run -DLXQT_LIBRARY_NAME:STRING="string"
|
||||
* remove not needed whitespaces
|
||||
* Adds StartOptions to the SingleApplication class
|
||||
* Adds the LxQt::SingleApplication class.
|
||||
* CMakeLists.txt maintenaince
|
||||
* Fixes yet another translations install dir mistake
|
||||
* Get rid of USE_QT5 in lxqt-config.cmake
|
||||
* Fixes translations install dir
|
||||
* Use the new LXQtTranslate modules.
|
||||
* Fixes Qt5LinguistToolsMacros file extension bug
|
||||
* Copied Qt5LinguistToolsMacros.cmake
|
||||
* Removes cmake commented code
|
||||
* Removes duplicates add_definitions()
|
||||
* Removes lxqt_translate_desktop() from the _use.cnake
|
||||
* Adds Qt5TranslationLoader cmake module
|
||||
* Fix HtmlDelegate and move it to its own file. Also get rid of X11 on CMakeLists.txt.
|
||||
* Delete XfitMan class. Fixes lxde/lxde-qt#226
|
||||
* Don't update (extract) translations by default.
|
||||
* Includes all LXQt translation modules
|
||||
* Adds automatic translations loaders for LXQt libs and apps
|
||||
* Adds LXQtTranslateDesktop module
|
||||
* Adds the LXQtranslateTs cmake module
|
||||
* Update Russian translation
|
||||
* Drop support for Qt4 in code
|
||||
* Clean up CMakeLists.txt and drop Qt 4 support
|
||||
* Add myself to the authors list
|
||||
* Use QString default constructor instead of ""
|
||||
|
||||
0.8.0 / 2014-10-13
|
||||
==================
|
||||
|
||||
* Release v0.8.0
|
||||
* Adds a translation loader for plugins
|
||||
* Adds Qt5 automatic load of self translations
|
||||
* Updates translations installation and search paths
|
||||
* Mark translations as loaded for the English locale
|
||||
* Updates translations
|
||||
* Generate source.ts when updating translations
|
||||
* Don't translate uic generated files
|
||||
* Fixes another QTranslator related memory leak
|
||||
* Simplify translate() code
|
||||
* Fixes an memory leak that occurs when no translation is found
|
||||
* Fixes lxde/lxde-qt#140 and lxde/lxqt-panel#54
|
||||
* Stop creating unused QTranslator instances.
|
||||
* Fix top-to-bottom layout x-coord calculation
|
||||
* Fix broken *.ts files and update to the latest strings.
|
||||
* Replace LXDE-Qt with LXQt.
|
||||
* Add -locations absolute option to lupdate so our *.ts files can contain informations about the source lines.
|
||||
* Fix incorrect namespace in the *.ts files.
|
||||
* Add code to update the *.ts files when the UPDATE_TRANSLATIONS option is turned on.
|
||||
* Fix context names which uses C++ namespaces in all of the *.ts files.
|
||||
* Add support for getting the hints' flags of a window
|
||||
* Skip leave confirmation dialogs depending on session settings
|
||||
* remove magic from cmake. USE_QT5 should be the only trigger
|
||||
* Use the "new" CMake FIND_PACKAGE case policy
|
||||
* Add include(${QTXDG_USE_FILE}) to Qt5 also.
|
||||
* Use the "new" CMake FIND_PACKAGE case policy
|
||||
* Adds missing libqtxdg dependency
|
||||
* Don't allow #include <lxqt-qt5/lxqtxxxxx.h>
|
||||
* Updates the Qt4 and Qt5 library names and related stuff
|
||||
* Use the same header namespace everywhere
|
||||
* Don't use undefined variables
|
||||
* Find liblxqt dependencies automatically
|
||||
* Removes another duplicated installation of a file
|
||||
* Removes duplicate installation of a file
|
||||
* Fixes extra misleading slashes in path names
|
||||
* Cleans commented unneeded stuff
|
||||
* Fix a typo in variable name
|
||||
* Update liblxqt_pl_PL.ts
|
||||
* Fix broken build of qt4 version
|
||||
* Use more portable Qt and qtxdg header names
|
||||
* Use newer version of cmake 2.8.9
|
||||
* Detect the path of qmake correctly for Qt5.
|
||||
* Fix internal include
|
||||
* Fix after merging from master, by removing dupplicated items
|
||||
* Merge branch 'master' of https://github.com/lxde/liblxqt into qt5
|
||||
* Update qt5 porting
|
||||
* Update Turkish tranlations
|
||||
* Set include dirs properly.
|
||||
* Install pkgconfig file to /usr/local/libdata/pkgconfig when FreeBSD is detected.
|
||||
* Set link directories properly
|
||||
* Use cmake export functionality.
|
||||
* Qt5 support (step 1)
|
||||
* Intree build
|
||||
|
||||
0.7.0 / 2014-05-07
|
||||
==================
|
||||
|
||||
* Release 0.7.0
|
||||
|
||||
0.6.99 / 2014-05-01
|
||||
===================
|
||||
|
||||
* Release 0.6.99 (0.7.0pre alpha)
|
||||
* Update the About dialog information
|
||||
* Update AUTHORS and COPYING
|
||||
* Add CPack rules for creating tarball
|
||||
* Fix incorrect arguments passing to logind
|
||||
* Don't append library suffix to library path and use it by default
|
||||
* CMakeLists.txt: Adds quotes to the lib string
|
||||
* Respect standard LIB_INSTALL_DIR
|
||||
* Reformats CMakeLists.txt to fit in an 80x24 terminal
|
||||
* Removes blank lines
|
||||
* Properly format about author dialog links
|
||||
* Removed CMAKE_SOURCE_DIR and CMAKE_BINARY_DIR usages from translatorsinfo/CMakeLists.txt
|
||||
* Retain old CMAKE_CXX_FLAGS while adding visibility stuff. Add -Wl,-no-undefined -Wall flags to ensure correctness.
|
||||
* Add missing file.
|
||||
* Use gcc visibility feature to decrease number of exported symbols to half.
|
||||
* Use the correct updated org.freedesktop.Notifications.xml file from razor-resources.
|
||||
* Restore previous XfitMan::moveWindowToDesktop() due to regression bugs.
|
||||
* Add setIconGeometry(), getShowingDesktop(), setShowingDesktop(), and getWMState() to Xfitman.
|
||||
* Fix renaming bugs, replacing lxqt-qt with lxde-qt
|
||||
* Finish the crazy razor=>lxqt renaming tasks.
|
||||
* Add logout support for lxsession.
|
||||
* Rename razor to lxqt in settings
|
||||
* find themes when they are located in /usr/local/...
|
||||
* Revert "header fix"
|
||||
* header fix
|
||||
* Add proper namespace to signal parameters due to the limitation of Qt moc system.
|
||||
* Rename razor to lxqt and fix XdgDir header inclusion.
|
||||
* Add missing namespace for LxQt::PowerManager.
|
||||
* Fix namespace for LxQt::xFitMan() to avoid undefined reference when linking with liblxqt.
|
||||
* The Translatator class added, all translations moved to /usr/<local>/share/lxde/transalations
|
||||
* Descriptions for translators
|
||||
* Razor-qt => LXDE-Qt on about dialog
|
||||
* Simplify translations script
|
||||
* Simplify translations script
|
||||
* All public files has lxqt prefix
|
||||
* XfitMan => LxQt::XfitMan
|
||||
* ScreenSaver => LxQt::ScreenSaver
|
||||
* RotatedWidget => LxQt::RotatedWidget
|
||||
* Razorsettings => LxQt::Settings
|
||||
* RazorPluginInfo => LxQt::PluginInfo
|
||||
* RazorNotification => LxQt::Notification
|
||||
* RazorGridLayout => LxQt::GridLayout
|
||||
* RazorAutostartEntry => LxQt::AutostartEntry
|
||||
* RazorApplication => LxQt::Application
|
||||
* ProgramFinder=>LxQt::ProgramFinder
|
||||
* RazorConfigDialog=>LxQt::ConfigDialog
|
||||
* Libtranslate => LxQt::LibTranslate
|
||||
* TranslatorsInfo => LxQt::TranslatorsInfo
|
||||
* Small code refactoring in the LxQt::Power
|
||||
* AddPluginDialog => LxQt::AddPluginDialog
|
||||
* RazorAboutDlg => LxQt::AboutDialog
|
||||
* RazorPower => LxQt::Power
|
||||
* Build errors, wrong include paths.
|
||||
* Cmake find_package files
|
||||
* Fix broken CMakeLists.txt and make the lib compile again.
|
||||
* Make liblxqt (original librazorqt) compiles independently.
|
||||
* Add COPYING and AUTHORS files
|
||||
* Fix for Issue #571 [quicklaunch plugin]
|
||||
* Renames the "Add plugin" button to "Add Widget"
|
||||
* Removes hardcoded "Add plugin" window title
|
||||
* razorqt-desktop: Unify plugins and widgets names. Closes #447
|
||||
* More verbose constants
|
||||
* Type sign fixed
|
||||
* No dependencies on STL
|
||||
* Typo fixed
|
||||
* Issue #605 fixed. Double rendering removed
|
||||
* Theme change autodetection
|
||||
* Mouse event transparency is controllable in rotated widget
|
||||
* Old files removed
|
||||
* Rotated widget transits some mouse events
|
||||
* Helper functions added to Rotated widget
|
||||
* Rotated widget requires content
|
||||
* Rotated widget added
|
||||
* libraries: Removes unneeded include(RazorLibSuffix)
|
||||
* Initial version of Razor Screenlocker
|
||||
* ProgramFinder: a set of functions to check if programs are installed
|
||||
* issue #473: move count/active text into item header
|
||||
* initial implementation for #473 Highlight installed plugins. Now it needs to be "designed"
|
||||
* Change "leave"-button in razor-lightdm-greeter to a menu button. Fix #323
|
||||
* Fix typos
|
||||
* Add RazorGridLayout::setCellXXXWidth, RazorGridLayout::setCellXXXHeight and RazorGridLayout::setCellFixedXXX, functions
|
||||
* Fix for Issues #564 "new panel: cfg "Line size" can be set to 10px but the value is not accepted" #563 "new panel: vertical mode makes panel too lerge (width)"
|
||||
* Add moveItem method to RazorGridLayout
|
||||
* Close Issue #541
|
||||
* Close Issue #541
|
||||
* RazorGridLayout handle new item incorrectlly
|
||||
* Fix translators' webpage links
|
||||
* Update layout when plugin shows.
|
||||
* Improved razorpanellayout and new razorgridlayout.
|
||||
* Add autostart entry API into the library
|
||||
* xfitman: try to get window title even harder
|
||||
* New panel layout and many changes
|
||||
* Improve icons handling.
|
||||
* Added missing license header in the technicalinfo
|
||||
* Make it possible to load translations for multiple libraries
|
||||
* About dialog: Reword authors tab
|
||||
* Added "Copy to clipboard" button to razor-about->technical information.
|
||||
* Don't "fail" when a dbus call returns no value
|
||||
* Trtanslations
|
||||
* Razor-panel: New plugin API
|
||||
* Simplify code in the PowerManager
|
||||
* Do not display non-urgent notifications in fallback mode
|
||||
* razor-power: add systemd support
|
||||
* Change license for xfitman
|
||||
* BSD does not handle the way with two consecutive slashes.
|
||||
* Translations updated
|
||||
* Translations updated
|
||||
* first part of fixes based on Coverity Scan (code static analysis)
|
||||
* Fix components missing translations
|
||||
* razor-about: Authors text changed
|
||||
* Translations
|
||||
* Delete bad en_GB translations
|
||||
* Update translations
|
||||
* Minor fixes
|
||||
* Translations updated
|
||||
* Removed line num from TS files.
|
||||
* Translators info & refactoring of the About dialog
|
||||
* Replace <p> tag with newlines since it's not valid notification markup
|
||||
* Add a fallback provider for those without UPower/CK
|
||||
* Don't write on every RazorSettings initialization
|
||||
* Translations
|
||||
* Fixed librazorqt.qm directory
|
||||
* Translations for librazorqt
|
||||
* fixed #412 Panel plugin configuration is broken
|
||||
* optional debugging when there is RAZOR_DEBUG env.var. set
|
||||
* fix for infinite event loop on panel start in power manager when there is no DBUS/notificationd running. The QMessageBox should not be displayed on init.
|
||||
* fixed #349 RazorSettings settingsChanged signal is not emitted
|
||||
* razor-desktop reworked to enable future features and fix RTTI related crashes.
|
||||
* Update libraries/razorqt/screensaver.cpp
|
||||
* Sort plugins in the "Add plugin dialog"
|
||||
* Updated ts.src files
|
||||
* part of #329: on-click on notification launces default action or it tries to find appropariate window to raise; xfitman method renamed + one new
|
||||
* extended "razor-about" implementation. Resolves #253
|
||||
* Add capabilities and server information functions
|
||||
* Improve RazorNotification docs
|
||||
* Add Hints support
|
||||
* notifications: vrious fixes; more options (hardcoded values removed); layouting
|
||||
* notifications: razorapplication used (theming); qtxdg used; spec icon loading implemented
|
||||
* Implement Actions and add some more functions
|
||||
* Implement new RazorNotification class
|
||||
* Remove RazorNotification classes (no license/copyright)
|
||||
* Ts.src files updated.
|
||||
* Language name zh_CN.GB2312 braked cmake process.
|
||||
* Translations updated
|
||||
* Split sessionconfigwindow and remove old module config
|
||||
* fixed #284 qmmp its not registered in window list panel and properly fixed #81 Qlipper should not appear in Task Manager
|
||||
* fixed #277 cmake installs private class
|
||||
* Small improvement to dialog icon sizing
|
||||
* Don't reset when pressing Enter
|
||||
* reduce error messages when there is no session running in razor-power
|
||||
* QDbusError canot be print out on Ubuntu version of qt
|
||||
* notification client library uses a QMessageBox failback message when it's not able to send a dbus message
|
||||
* fixed #147 razorpower: things to implement - notifications
|
||||
* default arguments for notification client lib
|
||||
* Fix default wallpaper loading
|
||||
* GUI for change razor theme.
|
||||
* Moving qtservice to libraries
|
||||
* Stylesheets are not always applied.
|
||||
* Typos in code. Thanks Aaron Lewis. * In razor-runner , providers item: title() was typed as tile() * For RazorSettings class , settingsChanged() was typed as settigsChanged()
|
||||
* RazorSettings not read global settings.
|
||||
* Changing notification ui. Adding default notitifaction icon. Embedding icons in notification
|
||||
* Proper default values
|
||||
* Proper id number assigned to notifications Properly remove notification by quint32 id
|
||||
* Remove custom settings, use razor ones
|
||||
* Adding razor-config-notificationd
|
||||
* Moving notification client library to razorqt
|
||||
* Don't try to print in color if it's not a terminal
|
||||
* Use QSS for setting single-click mode
|
||||
* Refactor desktop config to use RazorConfigDialog
|
||||
* Revert "Global shortcuts now based on PSI code."
|
||||
* Global shortcuts now based on PSI code
|
||||
* better path for logging in DEBUG mode
|
||||
* fix for theme loading when there is no theme specified in config
|
||||
* Added localizedValue() in RazorSettings
|
||||
* Fix: wrong path for debug log
|
||||
* Config coresponds XDG directory specification
|
||||
* Transifex desktop: sr_BA.ts should be a local
|
||||
* strongly enhances debugging
|
||||
* Transifex desktop: local translations
|
||||
* Transifex desktop: Translations pulled
|
||||
* fixed #218 Use <razor-dir>/session.log instead of ~/.razor-session.log
|
||||
* Icons for the desktop menu
|
||||
* Add Traditional Chinese Translations
|
||||
* Translations update
|
||||
* Added support for the online translation service. www.transifex.net
|
||||
* RazorApplication class implemented; all modules ported to this class
|
||||
* Serbian translation files
|
||||
* Greek translation by iosifidis
|
||||
* Added danish translations
|
||||
* Russian translation
|
||||
* Fix for issue #100
|
||||
* Fix for issue #100
|
||||
* fix #169: italian translation
|
||||
* Lock the screen when "Lock Screen" is selected
|
||||
* Update icons change when theme changes
|
||||
* Add function to use alternative icons
|
||||
* Env variables for plugins dirs RAZORQT_DESKTOP_PLUGINS_DIR & RAZORQT_DESKTOP_PLUGINS_SO_DIR RAZORQT_PANEL_PLUGINS_DIR & RAZORQT_PANEL_PLUGINS_SO_DIR
|
||||
* Create a "standardized" configuration dialog
|
||||
* Relicense razorqtlib
|
||||
* XdgAutoStart rewriten (lgpl2+)
|
||||
* Fix gmail.ru -> gmail.com
|
||||
* Issue#147 add return value to provide a valuable feedback to user
|
||||
* menus are adopted to the new backends; old code removed; check for running razor-session to allow/disallow "logout" item
|
||||
* Czech translations (cs_CZ)
|
||||
* New power engine & razor-power program
|
||||
* Make XDG autostart fully editable
|
||||
* unneeded code removed
|
||||
* Update german [de] translation
|
||||
* Let XdgAutoStart return Hidden files, and save modified files
|
||||
* Correct the XdgAutoStart behavior
|
||||
* SVK translation finalized
|
||||
* Replaces return"" by return QString()
|
||||
* Initial german [de] translation
|
||||
* Fix issue #116
|
||||
* License audit
|
||||
* implemented #70: pkg-config for libs
|
||||
* Add Chinese(simplified) translation files.
|
||||
* License audit
|
||||
* razorqt: add find_package(X11) as ${X11_X11_LIB} is used
|
||||
* Add Slovak (sk) translation
|
||||
* Typo in russian translation
|
||||
* Czech translations (cs_CZ)
|
||||
* A-MeGo Theme
|
||||
* fix for crashes when there is no upower
|
||||
* fix for powermanager. These dbus calls are pain...
|
||||
* New doxygen ifrastructure
|
||||
* power manager: list actions only if is user allowed to call it
|
||||
* fixed warning: The Free Software Foundation address in this file seems to be outdated
|
||||
* devel-docs generated in CMAKE_BINARY_DIR/docs includig dummy index.html
|
||||
* missing translations in CMakeLists
|
||||
* XdgDesktopFile is implicitly shared
|
||||
* huge refactoring of the libraries build organization
|
@ -1,347 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)
|
||||
|
||||
project(liblxqt)
|
||||
|
||||
set(QT_MINIMUM_VERSION "5.5.0")
|
||||
set(QTXDG_MINIMUM_VERSION "3.1.0")
|
||||
set(LXQTBT_MINIMUM_VERSION "0.4.0")
|
||||
|
||||
# Major LXQt Version, belong to all components
|
||||
set(LXQT_MAJOR_VERSION 0)
|
||||
# Minor LXQt Version, belong to all components
|
||||
set(LXQT_MINOR_VERSION 12)
|
||||
#
|
||||
# Patch Version, belong *only* to the component
|
||||
# LXQt is 0.11 - liblxqt is at patch version 1
|
||||
# The official LXQt version will follow liblxqt.
|
||||
#
|
||||
# In a perfect world all components would have the same major- and minor- and
|
||||
# patch-version as liblxqt - in real life it will be fine if every component
|
||||
# has it's own patch version within a major/minor life cyle.
|
||||
#
|
||||
set(LXQT_PATCH_VERSION 0)
|
||||
set(LXQT_VERSION ${LXQT_MAJOR_VERSION}.${LXQT_MINOR_VERSION}.${LXQT_PATCH_VERSION})
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
include(GNUInstallDirs) # Standard directories for installation
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Release is the default build type
|
||||
#-----------------------------------------------------------------------------
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif()
|
||||
|
||||
set(LXQT_PKG_CONFIG_DESCRIPTION "Shared library for LXQt applications")
|
||||
|
||||
set(PUB_HDRS
|
||||
lxqthtmldelegate.h
|
||||
lxqtsettings.h
|
||||
lxqtplugininfo.h
|
||||
lxqtpowermanager.h
|
||||
lxqtscreensaver.h
|
||||
lxqtapplication.h
|
||||
lxqtsingleapplication.h
|
||||
lxqttranslator.h
|
||||
lxqtprogramfinder.h
|
||||
|
||||
configdialog/lxqtconfigdialog.h
|
||||
configdialog/lxqtpageselectwidget.h
|
||||
|
||||
lxqtpower/lxqtpower.h
|
||||
lxqtnotification.h
|
||||
lxqtautostartentry.h
|
||||
lxqtgridlayout.h
|
||||
lxqtrotatedwidget.h
|
||||
lxqtglobals.h
|
||||
)
|
||||
|
||||
set(PUBLIC_CLASSES
|
||||
HtmlDelegate
|
||||
Settings
|
||||
PluginInfo
|
||||
PowerManager
|
||||
ScreenSaver
|
||||
Application
|
||||
SingleApplication
|
||||
Translator
|
||||
ProgramFinder
|
||||
|
||||
ConfigDialog
|
||||
PageSelectWidget
|
||||
|
||||
Power
|
||||
Notification
|
||||
AutostartEntry
|
||||
GridLayout
|
||||
RotatedWidget
|
||||
)
|
||||
|
||||
set(SRCS
|
||||
lxqthtmldelegate.cpp
|
||||
lxqtplugininfo.cpp
|
||||
lxqtpowermanager.cpp
|
||||
lxqtsettings.cpp
|
||||
lxqtscreensaver.cpp
|
||||
lxqtapplication.cpp
|
||||
lxqtsingleapplication.cpp
|
||||
lxqttranslator.cpp
|
||||
lxqtprogramfinder.cpp
|
||||
|
||||
configdialog/lxqtconfigdialog.cpp
|
||||
configdialog/lxqtpageselectwidget.cpp
|
||||
|
||||
lxqtpower/lxqtpower.cpp
|
||||
lxqtpower/lxqtpowerproviders.cpp
|
||||
lxqtautostartentry.cpp
|
||||
lxqtnotification.cpp
|
||||
lxqtgridlayout.cpp
|
||||
lxqtrotatedwidget.cpp
|
||||
)
|
||||
|
||||
set(MOCS
|
||||
lxqthtmldelegate.h
|
||||
lxqtpowermanager.h
|
||||
lxqtsettings.h
|
||||
lxqtscreensaver.h
|
||||
lxqtapplication.h
|
||||
|
||||
configdialog/lxqtconfigdialog.h
|
||||
configdialog/lxqtpageselectwidget.h
|
||||
|
||||
lxqtnotification.h
|
||||
lxqtnotification_p.h
|
||||
lxqtpower/lxqtpower.h
|
||||
lxqtpower/lxqtpowerproviders.h
|
||||
lxqtgridlayout.h
|
||||
lxqtrotatedwidget.h
|
||||
)
|
||||
|
||||
set(FORMS
|
||||
configdialog/lxqtconfigdialog.ui
|
||||
)
|
||||
|
||||
option(UPDATE_TRANSLATIONS "Update source translation translations/*.ts files" OFF)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
|
||||
find_package(lxqt-build-tools ${LXQTBT_MINIMUM_VERSION} REQUIRED)
|
||||
find_package(X11 REQUIRED QUIET)
|
||||
find_package(Qt5 ${QT_MINIMUM_VERSION} CONFIG REQUIRED Widgets DBus X11Extras LinguistTools)
|
||||
find_package(Qt5Xdg ${QTXDG_MINIMUM_VERSION} REQUIRED)
|
||||
find_package(KF5WindowSystem REQUIRED QUIET)
|
||||
message(STATUS "Building ${PROJECT_NAME} with Qt ${Qt5Core_VERSION}")
|
||||
|
||||
QT5_ADD_DBUS_INTERFACE(SRCS
|
||||
dbus/org.freedesktop.Notifications.xml
|
||||
notifications_interface
|
||||
)
|
||||
|
||||
QT5_ADD_DBUS_ADAPTOR(SRCS
|
||||
dbus/org.lxqt.SingleApplication.xml
|
||||
lxqtsingleapplication.h LXQt::SingleApplication
|
||||
)
|
||||
|
||||
|
||||
# KF5WindowSystem is missing here. KF5WindowSystem doesn't provide an .pc file.
|
||||
set(LXQT_PKG_CONFIG_REQUIRES "Qt5Xdg >= ${QTXDG_MINIMUM_VERSION}, Qt5Widgets >= ${QT_MINIMUM_VERSION}, Qt5Xml >= ${QT_MINIMUM_VERSION}, Qt5DBus >= ${QT_MINIMUM_VERSION}, Qt5X11Extras >= ${QT_MINIMUM_VERSION}")
|
||||
|
||||
|
||||
# Standard directories for installation
|
||||
include(LXQtCompilerSettings NO_POLICY_SCOPE)
|
||||
include(LXQtCreatePkgConfigFile)
|
||||
include(LXQtCreatePortableHeaders)
|
||||
include(LXQtConfigVars)
|
||||
|
||||
set(LXQT_INTREE_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/include")
|
||||
|
||||
set(LXQT_INSTALL_INCLUDE_DIR "${CMAKE_INSTALL_FULL_INCLUDEDIR}/${LXQT_LIBRARY_NAME}")
|
||||
set(LXQT_INSTALL_CMAKE_DIR "${CMAKE_INSTALL_FULL_DATAROOTDIR}/cmake")
|
||||
|
||||
|
||||
## Translations
|
||||
include(LXQtTranslateTs)
|
||||
|
||||
lxqt_translate_ts(QM_FILES
|
||||
UPDATE_TRANSLATIONS
|
||||
${UPDATE_TRANSLATIONS}
|
||||
SOURCES
|
||||
${SRCS}
|
||||
${FORMS}
|
||||
INSTALL_DIR
|
||||
"${LXQT_TRANSLATIONS_DIR}/${PROJECT_NAME}"
|
||||
PULL_TRANSLATIONS
|
||||
${PULL_TRANSLATIONS}
|
||||
CLEAN_TRANSLATIONS
|
||||
${CLEAN_TRANSLATIONS}
|
||||
TRANSLATIONS_REPO
|
||||
${TRANSLATIONS_REPO}
|
||||
TRANSLATIONS_REFSPEC
|
||||
${TRANSLATIONS_REFSPEC}
|
||||
)
|
||||
|
||||
message(STATUS "")
|
||||
message(STATUS "liblxqt version: ${LXQT_VERSION}")
|
||||
message(STATUS "")
|
||||
|
||||
|
||||
# Copy public headers
|
||||
foreach(h ${PUB_HDRS})
|
||||
get_filename_component(bh ${h} NAME)
|
||||
configure_file(${h} "${LXQT_INTREE_INCLUDE_DIR}/LXQt/${bh}" COPYONLY)
|
||||
endforeach()
|
||||
|
||||
# Create the portable headers
|
||||
lxqt_create_portable_headers(INTREE_PORTABLE_HEADERS
|
||||
NAME_PREFIX "lxqt"
|
||||
OUTPUT_DIR "${LXQT_INTREE_INCLUDE_DIR}/LXQt"
|
||||
HEADER_NAMES ${PUBLIC_CLASSES}
|
||||
)
|
||||
|
||||
#check_portable_headers(H_FILES ${PUB_HDRS} LINKS "${INTREE_PORTABLE_HEADERS}")
|
||||
|
||||
#************************************************
|
||||
# Create in-tree build infrastructure
|
||||
#************************************************
|
||||
set(CFG_LXQT_TARGETS_FILE "${LXQT_INTREE_TARGETS_FILE}")
|
||||
|
||||
configure_package_config_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/lxqt-config.cmake.in"
|
||||
"${CMAKE_BINARY_DIR}/${LXQT_LIBRARY_NAME}-config.cmake"
|
||||
INSTALL_DESTINATION "neverland" # required, altough we don't install it
|
||||
)
|
||||
|
||||
#************************************************
|
||||
# Create installable build infrastructure
|
||||
#************************************************
|
||||
set(CFG_LXQT_TARGETS_FILE "${LXQT_INSTALL_CMAKE_DIR}/${LXQT_LIBRARY_NAME}/${LXQT_LIBRARY_NAME}-targets.cmake")
|
||||
|
||||
configure_package_config_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/lxqt-config.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/install/${LXQT_LIBRARY_NAME}-config.cmake"
|
||||
INSTALL_DESTINATION "${LXQT_INSTALL_CMAKE_DIR}/${LXQT_LIBRARY_NAME}"
|
||||
)
|
||||
|
||||
write_basic_package_version_file(
|
||||
"${CMAKE_BINARY_DIR}/${LXQT_LIBRARY_NAME}-config-version.cmake"
|
||||
VERSION ${LXQT_VERSION}
|
||||
COMPATIBILITY AnyNewerVersion
|
||||
)
|
||||
|
||||
install(FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/install/${LXQT_LIBRARY_NAME}-config.cmake"
|
||||
"${CMAKE_BINARY_DIR}/${LXQT_LIBRARY_NAME}-config-version.cmake"
|
||||
DESTINATION "${LXQT_INSTALL_CMAKE_DIR}/${LXQT_LIBRARY_NAME}"
|
||||
COMPONENT Devel
|
||||
)
|
||||
|
||||
install(EXPORT
|
||||
${LXQT_LIBRARY_NAME}-targets
|
||||
DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${LXQT_LIBRARY_NAME}"
|
||||
COMPONENT Devel
|
||||
)
|
||||
|
||||
add_library(${LXQT_LIBRARY_NAME}
|
||||
SHARED ${PUB_HDRS}
|
||||
${SRCS}
|
||||
${dbus_generated}
|
||||
${UIS} ${MOCS}
|
||||
${QM_FILES}
|
||||
${QRC_CXX_SOURCES}
|
||||
|
||||
)
|
||||
|
||||
target_link_libraries(${LXQT_LIBRARY_NAME}
|
||||
PUBLIC
|
||||
KF5::WindowSystem
|
||||
Qt5::Widgets
|
||||
Qt5::DBus
|
||||
Qt5::X11Extras
|
||||
Qt5Xdg
|
||||
PRIVATE
|
||||
${X11_Xscreensaver_LIB}
|
||||
${X11_X11_LIB}
|
||||
)
|
||||
|
||||
set_target_properties(${LXQT_LIBRARY_NAME} PROPERTIES
|
||||
VERSION ${LXQT_VERSION}
|
||||
SOVERSION ${LXQT_MAJOR_VERSION}
|
||||
)
|
||||
|
||||
target_compile_definitions(${LXQT_LIBRARY_NAME}
|
||||
PRIVATE
|
||||
"LXQT_RELATIVE_SHARE_DIR=\"${LXQT_RELATIVE_SHARE_DIR}\""
|
||||
"LXQT_SHARE_DIR=\"${LXQT_SHARE_DIR}\""
|
||||
"LXQT_RELATIVE_SHARE_TRANSLATIONS_DIR=\"${LXQT_RELATIVE_TRANSLATIONS_DIR}\""
|
||||
"LXQT_SHARE_TRANSLATIONS_DIR=\"${LXQT_TRANSLATIONS_DIR}\""
|
||||
"LXQT_GRAPHICS_DIR=\"${LXQT_GRAPHICS_DIR}\""
|
||||
"LXQT_ETC_XDG_DIR=\"${LXQT_ETC_XDG_DIR}\""
|
||||
"LXQT_DATA_DIR=\"${LXQT_DATA_DIR}\""
|
||||
"LXQT_INSTALL_PREFIX=\"${CMAKE_INSTALL_PREFIX}\""
|
||||
"LXQT_VERSION=\"${LXQT_VERSION}\""
|
||||
"COMPILE_LIBLXQT"
|
||||
"$<$<CONFIG:Release>:QT_NO_DEBUG_OUTPUT>"
|
||||
"$<$<CONFIG:Release>:QT_NO_WARNING_OUTPUT>"
|
||||
)
|
||||
|
||||
if (Qt5Core_VERSION VERSION_LESS "5.9.0")
|
||||
if (NOT DEFINED WITH_XDG_DIRS_FALLBACK)
|
||||
set(WITH_XDG_DIRS_FALLBACK ON)
|
||||
endif ()
|
||||
elseif (WITH_XDG_DIRS_FALLBACK)
|
||||
set(WITH_XDG_DIRS_FALLBACK OFF)
|
||||
message(WARNING "Disabling requested WITH_XDG_DIRS_FALLBACK workaround, as proper implementation is in Qt from v5.9.0")
|
||||
endif ()
|
||||
if (WITH_XDG_DIRS_FALLBACK)
|
||||
message(STATUS "Building with homemade QSettings XDG fallback workaround")
|
||||
target_compile_definitions(${LXQT_LIBRARY_NAME}
|
||||
PRIVATE "WITH_XDG_DIRS_FALLBACK"
|
||||
)
|
||||
endif ()
|
||||
|
||||
target_include_directories(${LXQT_LIBRARY_NAME}
|
||||
INTERFACE
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${LXQT_LIBRARY_NAME}>"
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${LXQT_LIBRARY_NAME}/LXQt>"
|
||||
"$<BUILD_INTERFACE:${LXQT_INTREE_INCLUDE_DIR}>"
|
||||
"$<BUILD_INTERFACE:${LXQT_INTREE_INCLUDE_DIR}/LXQt>"
|
||||
)
|
||||
|
||||
install(TARGETS
|
||||
${LXQT_LIBRARY_NAME}
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
EXPORT ${LXQT_LIBRARY_NAME}-targets
|
||||
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
COMPONENT Runtime
|
||||
)
|
||||
|
||||
install(FILES
|
||||
${PUB_HDRS}
|
||||
DESTINATION "${LXQT_INSTALL_INCLUDE_DIR}/LXQt"
|
||||
COMPONENT Devel
|
||||
)
|
||||
|
||||
install(FILES
|
||||
${INTREE_PORTABLE_HEADERS}
|
||||
DESTINATION "${LXQT_INSTALL_INCLUDE_DIR}/LXQt"
|
||||
COMPONENT Devel
|
||||
)
|
||||
|
||||
#************************************************
|
||||
# Create and install pkgconfig file
|
||||
#************************************************
|
||||
lxqt_create_pkgconfig_file(
|
||||
PACKAGE_NAME ${LXQT_LIBRARY_NAME}
|
||||
DESCRIPTIVE_NAME ${LXQT_LIBRARY_NAME}
|
||||
DESCRIPTION ${LXQT_PKG_CONFIG_DESCRIPTION}
|
||||
INCLUDEDIRS ${LXQT_LIBRARY_NAME}
|
||||
LIBS ${LXQT_LIBRARY_NAME}
|
||||
REQUIRES ${LXQT_PKG_CONFIG_REQUIRES}
|
||||
VERSION ${LXQT_VERSION}
|
||||
INSTALL
|
||||
)
|
||||
#************************************************
|
@ -1,458 +0,0 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 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.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
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 and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, 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 library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete 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 distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
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 Library or any portion
|
||||
of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
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 Library, 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 Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you 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.
|
||||
|
||||
If distribution of 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 satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be 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.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library 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.
|
||||
|
||||
9. 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 Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
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 with
|
||||
this License.
|
||||
|
||||
11. 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 Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library 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 Library.
|
||||
|
||||
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.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library 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.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser 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 Library
|
||||
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 Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
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
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "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
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. 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 LIBRARY 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
|
||||
LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
@ -1,20 +0,0 @@
|
||||
# liblxqt
|
||||
|
||||
## Overview
|
||||
|
||||
`liblxqt` represents the core library of LXQt providing essential functionality needed by nearly all of its components.
|
||||
|
||||
## Installation
|
||||
|
||||
### Sources
|
||||
|
||||
Its runtime dependencies are libxss, KWindowSystem, qtbase, qtx11extras and [libqtxdg](https://github.com/lxde/libqtxdg).
|
||||
Additional build dependencies are CMake and optionally Git to pull latest VCS checkouts. The localization files were outsourced to repository [lxqt-l10n](https://github.com/lxde/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. CMake variable `CMAKE_INSTALL_PREFIX` will normally have to be set to `/usr`, depending on the way library paths are dealt with on 64bit systems variables like `CMAKE_INSTALL_LIBDIR` may have to be set as well.
|
||||
|
||||
To build run `make`, to install `make install` which accepts variable `DESTDIR` as usual.
|
||||
|
||||
### Binary packages
|
||||
|
||||
The library is provided by all major Linux distributions like Arch Linux, Debian, Fedora and openSUSE. Just use your package manager to search for string `liblxqt`.
|
@ -1,37 +0,0 @@
|
||||
# - Finds the lxqt package
|
||||
|
||||
@PACKAGE_INIT@
|
||||
|
||||
if (CMAKE_VERSION VERSION_LESS 3.0.2)
|
||||
message(FATAL_ERROR \"@PROJECT_NAME@ requires at least CMake version 3.0.2\")
|
||||
endif()
|
||||
|
||||
include(CMakeFindDependencyMacro)
|
||||
|
||||
find_dependency(Qt5Widgets @QT_MINIMUM_VERSION@)
|
||||
find_dependency(Qt5DBus @QT_MINIMUM_VERSION@)
|
||||
find_dependency(Qt5X11Extras @QT_MINIMUM_VERSION@)
|
||||
find_dependency(Qt5LinguistTools @QT_MINIMUM_VERSION@)
|
||||
find_dependency(Qt5Xdg @QTXDG_MINIMUM_VERSION@)
|
||||
find_dependency(KF5WindowSystem)
|
||||
find_dependency(lxqt-build-tools @LXQTBT_MINIMUM_VERSION@)
|
||||
include(LXQtConfigVars)
|
||||
|
||||
|
||||
# - Set version informations
|
||||
set(LXQT_MAJOR_VERSION "@LXQT_MAJOR_VERSION@")
|
||||
set(LXQT_MINOR_VERSION "@LXQT_MINOR_VERSION@")
|
||||
set(LXQT_PATCH_VERSION "@LXQT_PATCH_VERSION@")
|
||||
set(LXQT_VERSION "@LXQT_VERSION@")
|
||||
|
||||
add_definitions("-DLXQT_MAJOR_VERSION=\"${LXQT_MAJOR_VERSION}\"")
|
||||
add_definitions("-DLXQT_MINOR_VERSION=\"${LXQT_MINOR_VERSION}\"")
|
||||
add_definitions("-DLXQT_PATCH_VERSION=\"${LXQT_PATCH_VERSION}\"")
|
||||
add_definitions("-DLXQT_VERSION=\"${LXQT_VERSION}\"")
|
||||
|
||||
if (NOT TARGET @LXQT_LIBRARY_NAME@)
|
||||
if (POLICY CMP0024)
|
||||
cmake_policy(SET CMP0024 NEW)
|
||||
endif()
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/lxqt-targets.cmake")
|
||||
endif()
|
@ -1,146 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright (C) 2012 Alec Moskvin <alecm@gmx.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
#include "lxqtconfigdialog.h"
|
||||
#include "ui_lxqtconfigdialog.h"
|
||||
|
||||
#include <XdgIcon>
|
||||
#include <QPushButton>
|
||||
|
||||
using namespace LXQt;
|
||||
|
||||
ConfigDialog::ConfigDialog(const QString& title, Settings* settings, QWidget* parent) :
|
||||
QDialog(parent),
|
||||
mSettings(settings),
|
||||
mCache(new SettingsCache(settings)),
|
||||
ui(new Ui::ConfigDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowTitle(title);
|
||||
connect(ui->buttons, SIGNAL(clicked(QAbstractButton*)), SLOT(dialogButtonsAction(QAbstractButton*)));
|
||||
ui->moduleList->setVisible(false);
|
||||
foreach(QPushButton* button, ui->buttons->findChildren<QPushButton*>())
|
||||
button->setAutoDefault(false);
|
||||
}
|
||||
|
||||
void ConfigDialog::setButtons(QDialogButtonBox::StandardButtons buttons)
|
||||
{
|
||||
ui->buttons->setStandardButtons(buttons);
|
||||
foreach(QPushButton* button, ui->buttons->findChildren<QPushButton*>())
|
||||
button->setAutoDefault(false);
|
||||
}
|
||||
|
||||
void ConfigDialog::addPage(QWidget* page, const QString& name, const QString& iconName)
|
||||
{
|
||||
addPage(page, name, QStringList() << iconName);
|
||||
}
|
||||
|
||||
void ConfigDialog::addPage(QWidget* page, const QString& name, const QStringList& iconNames)
|
||||
{
|
||||
Q_ASSERT(page);
|
||||
if (!page)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* We set the layout margin to 0. In the default configuration, one page
|
||||
* only, it aligns buttons with the page. In multi-page it saves a little
|
||||
* bit of space, without clutter.
|
||||
*/
|
||||
if (page->layout())
|
||||
{
|
||||
page->layout()->setMargin(0);
|
||||
}
|
||||
|
||||
QStringList icons = QStringList(iconNames) << "application-x-executable";
|
||||
new QListWidgetItem(XdgIcon::fromTheme(icons), name, ui->moduleList);
|
||||
mIcons.append(icons);
|
||||
ui->stackedWidget->addWidget(page);
|
||||
if(ui->stackedWidget->count() > 1)
|
||||
{
|
||||
ui->moduleList->setVisible(true);
|
||||
ui->moduleList->setCurrentRow(0);
|
||||
mMaxSize = QSize(qMax(page->geometry().width() + ui->moduleList->geometry().width(),
|
||||
mMaxSize.width()),
|
||||
qMax(page->geometry().height() + ui->buttons->geometry().height(),
|
||||
mMaxSize.height()));
|
||||
}
|
||||
else
|
||||
{
|
||||
mMaxSize = page->geometry().size();
|
||||
}
|
||||
resize(mMaxSize);
|
||||
}
|
||||
|
||||
void ConfigDialog::showPage(QWidget* page)
|
||||
{
|
||||
int index = ui->stackedWidget->indexOf(page);
|
||||
if (index < 0)
|
||||
return;
|
||||
|
||||
ui->stackedWidget->setCurrentIndex(index);
|
||||
ui->moduleList->setCurrentRow(index);
|
||||
}
|
||||
|
||||
bool ConfigDialog::event(QEvent * event)
|
||||
{
|
||||
if (QEvent::ThemeChange == event->type())
|
||||
updateIcons();
|
||||
return QDialog::event(event);
|
||||
}
|
||||
|
||||
void ConfigDialog::closeEvent(QCloseEvent* event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
emit save();
|
||||
mSettings->sync();
|
||||
}
|
||||
|
||||
void ConfigDialog::dialogButtonsAction(QAbstractButton* button)
|
||||
{
|
||||
QDialogButtonBox::StandardButton standardButton = ui->buttons->standardButton(button);
|
||||
emit clicked(standardButton);
|
||||
if (standardButton == QDialogButtonBox::Reset)
|
||||
{
|
||||
mCache->loadToSettings();
|
||||
emit reset();
|
||||
}
|
||||
else if(standardButton == QDialogButtonBox::Close)
|
||||
{
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigDialog::updateIcons()
|
||||
{
|
||||
for (int ix = 0; ix < mIcons.size(); ix++)
|
||||
ui->moduleList->item(ix)->setIcon(XdgIcon::fromTheme(mIcons.at(ix)));
|
||||
update();
|
||||
}
|
||||
|
||||
ConfigDialog::~ConfigDialog()
|
||||
{
|
||||
delete ui;
|
||||
delete mCache;
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright (C) 2012 Alec Moskvin <alecm@gmx.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
#ifndef LXQTCONFIGDIALOG_H
|
||||
#define LXQTCONFIGDIALOG_H
|
||||
|
||||
#include "lxqtsettings.h"
|
||||
#include <QDialog>
|
||||
#include <QAbstractButton>
|
||||
#include <QDialogButtonBox>
|
||||
#include "lxqtglobals.h"
|
||||
|
||||
namespace Ui {
|
||||
class ConfigDialog;
|
||||
}
|
||||
|
||||
namespace LXQt
|
||||
{
|
||||
|
||||
class LXQT_API ConfigDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ConfigDialog(const QString& title, Settings* settings, QWidget* parent = 0);
|
||||
|
||||
~ConfigDialog();
|
||||
|
||||
/*!
|
||||
* Sets buttons in button bar
|
||||
*/
|
||||
void setButtons(QDialogButtonBox::StandardButtons buttons);
|
||||
|
||||
/*!
|
||||
* Add a page to the configure dialog
|
||||
*/
|
||||
void addPage(QWidget* page, const QString& name, const QString& iconName="application-x-executable");
|
||||
|
||||
/*!
|
||||
* Add a page to the configure dialog, attempting several alternative icons to find one in the theme
|
||||
*/
|
||||
void addPage(QWidget* page, const QString& name, const QStringList& iconNames);
|
||||
|
||||
/*!
|
||||
* Show page containing the widget in parameter
|
||||
*/
|
||||
void showPage(QWidget *page);
|
||||
|
||||
|
||||
|
||||
signals:
|
||||
/*!
|
||||
* This signal is emitted when the user pressed the "Reset" button.
|
||||
* Settings should be re-read and the widgets should be set accordingly.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/*!
|
||||
* This is emitted whenever the window is closed and settings need to be saved.
|
||||
* It is only necessary if additional actions need to be performed - Settings are handled automatically.
|
||||
*/
|
||||
void save();
|
||||
|
||||
/*!
|
||||
* This is emitted when some button in the buttonbar is clicked.
|
||||
*/
|
||||
void clicked(QDialogButtonBox::StandardButton);
|
||||
|
||||
protected:
|
||||
Settings* mSettings;
|
||||
virtual bool event(QEvent * event) override;
|
||||
virtual void closeEvent(QCloseEvent* event) override;
|
||||
|
||||
private:
|
||||
SettingsCache* mCache;
|
||||
QList<QStringList> mIcons;
|
||||
QSize mMaxSize;
|
||||
Ui::ConfigDialog* ui;
|
||||
|
||||
private slots:
|
||||
void dialogButtonsAction(QAbstractButton* button);
|
||||
void updateIcons();
|
||||
|
||||
};
|
||||
|
||||
} // namespace LXQt
|
||||
#endif // LXQTCONFIGDIALOG_H
|
@ -1,84 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ConfigDialog</class>
|
||||
<widget class="QWidget" name="ConfigDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>272</width>
|
||||
<height>231</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="LXQt::PageSelectWidget" name="moduleList">
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="stackedWidget">
|
||||
<property name="currentIndex">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttons">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close|QDialogButtonBox::Reset</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LXQt::PageSelectWidget</class>
|
||||
<extends>QListWidget</extends>
|
||||
<header location="global">configdialog/lxqtpageselectwidget.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>moduleList</tabstop>
|
||||
<tabstop>buttons</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>moduleList</sender>
|
||||
<signal>currentRowChanged(int)</signal>
|
||||
<receiver>stackedWidget</receiver>
|
||||
<slot>setCurrentIndex(int)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>150</x>
|
||||
<y>123</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>344</x>
|
||||
<y>117</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
@ -1,157 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright: 2010-2011 Razor team
|
||||
* Authors:
|
||||
* Alexander Sokoloff <sokoloff.a@gmail.com>
|
||||
*
|
||||
* This program or library is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
|
||||
#include "lxqtpageselectwidget.h"
|
||||
#include <QDebug>
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QEvent>
|
||||
#include <QScrollBar>
|
||||
#include <QApplication>
|
||||
|
||||
using namespace LXQt;
|
||||
|
||||
class PageSelectWidgetItemDelegate: public QStyledItemDelegate
|
||||
{
|
||||
public:
|
||||
explicit PageSelectWidgetItemDelegate(PageSelectWidget *parent = 0);
|
||||
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
|
||||
private:
|
||||
PageSelectWidget* mView;
|
||||
};
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
PageSelectWidgetItemDelegate::PageSelectWidgetItemDelegate(PageSelectWidget *parent):
|
||||
QStyledItemDelegate(parent),
|
||||
mView(parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
QSize PageSelectWidgetItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
QSize size = QStyledItemDelegate::sizeHint(option, index);
|
||||
//all items should have unified width
|
||||
QStyle * style = option.widget ? option.widget->style() : QApplication::style();
|
||||
//Note: this margin logic follows code in QCommonStylePrivate::viewItemLayout()
|
||||
const int margin = style->pixelMetric(QStyle::PM_FocusFrameHMargin, &option, option.widget) + 1;
|
||||
//considering the icon size too
|
||||
size.setWidth(qMax(mView->maxTextWidth(), option.decorationSize.width()));
|
||||
size.rwidth() += 2 * margin;
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
PageSelectWidget::PageSelectWidget(QWidget *parent) :
|
||||
QListWidget(parent)
|
||||
, mMaxTextWidth(0)
|
||||
{
|
||||
setSelectionRectVisible(false);
|
||||
setViewMode(IconMode);
|
||||
setSpacing(2);
|
||||
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding);
|
||||
setWordWrap(true);
|
||||
setDragEnabled(NoDragDrop);
|
||||
setEditTriggers(NoEditTriggers);
|
||||
setTextElideMode(Qt::ElideNone);
|
||||
setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
setItemDelegate(new PageSelectWidgetItemDelegate(this));
|
||||
connect(model(), &QAbstractItemModel::rowsInserted, this, &PageSelectWidget::updateMaxTextWidth);
|
||||
connect(model(), &QAbstractItemModel::rowsRemoved, this, &PageSelectWidget::updateMaxTextWidth);
|
||||
connect(model(), &QAbstractItemModel::dataChanged, this, &PageSelectWidget::updateMaxTextWidth);
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
PageSelectWidget::~PageSelectWidget()
|
||||
{
|
||||
}
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
int PageSelectWidget::maxTextWidth() const
|
||||
{
|
||||
return mMaxTextWidth;
|
||||
}
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
QSize PageSelectWidget::viewportSizeHint() const
|
||||
{
|
||||
const int spacing2 = spacing() * 2;
|
||||
QSize size{sizeHintForColumn(0) + spacing2, (sizeHintForRow(0) + spacing2) * count()};
|
||||
if (verticalScrollBar()->isVisible())
|
||||
size.rwidth() += verticalScrollBar()->sizeHint().width();
|
||||
return size;
|
||||
}
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
QSize PageSelectWidget::minimumSizeHint() const
|
||||
{
|
||||
return QSize{0, 0};
|
||||
}
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
void PageSelectWidget::updateMaxTextWidth()
|
||||
{
|
||||
for(int i = count() - 1; 0 <= i; --i)
|
||||
{
|
||||
const QRect r = fontMetrics().boundingRect(QRect{}, Qt::AlignLeft | Qt::TextWordWrap, item(i)->text());
|
||||
mMaxTextWidth = qMax(mMaxTextWidth, r.width());
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
bool PageSelectWidget::event(QEvent * event)
|
||||
{
|
||||
if (QEvent::StyleChange == event->type())
|
||||
updateMaxTextWidth();
|
||||
|
||||
return QListWidget::event(event);
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright: 2010-2011 Razor team
|
||||
* Authors:
|
||||
* Alexander Sokoloff <sokoloff.a@gmail.com>
|
||||
*
|
||||
* This program or library is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
|
||||
#ifndef LXQTPAGESELECTWIDGET_H
|
||||
#define LXQTPAGESELECTWIDGET_H
|
||||
|
||||
#include "lxqtglobals.h"
|
||||
#include <QListWidget>
|
||||
|
||||
namespace LXQt
|
||||
{
|
||||
|
||||
class LXQT_API PageSelectWidget : public QListWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PageSelectWidget(QWidget *parent = 0);
|
||||
virtual ~PageSelectWidget();
|
||||
int maxTextWidth() const;
|
||||
bool event(QEvent * event) override;
|
||||
|
||||
protected:
|
||||
QSize viewportSizeHint() const override;
|
||||
QSize minimumSizeHint() const override;
|
||||
|
||||
protected slots:
|
||||
void updateMaxTextWidth();
|
||||
|
||||
private:
|
||||
int mMaxTextWidth;
|
||||
};
|
||||
|
||||
} // namespace LXQt
|
||||
#endif // PAGESELECTWIDGET_H
|
@ -1,69 +0,0 @@
|
||||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||
<!--
|
||||
Based on the output of command:
|
||||
qdbus org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.DBus.Introspectable.Introspect
|
||||
against xfce4-notifyd
|
||||
-->
|
||||
<node>
|
||||
<!--interface name="org.freedesktop.DBus.Introspectable">
|
||||
<method name="Introspect">
|
||||
<arg name="data" direction="out" type="s"/>
|
||||
</method>
|
||||
</interface>
|
||||
<interface name="org.freedesktop.DBus.Properties">
|
||||
<method name="Get">
|
||||
<arg name="interface" direction="in" type="s"/>
|
||||
<arg name="propname" direction="in" type="s"/>
|
||||
<arg name="value" direction="out" type="v"/>
|
||||
</method>
|
||||
<method name="Set">
|
||||
<arg name="interface" direction="in" type="s"/>
|
||||
<arg name="propname" direction="in" type="s"/>
|
||||
<arg name="value" direction="in" type="v"/>
|
||||
</method>
|
||||
<method name="GetAll">
|
||||
<arg name="interface" direction="in" type="s"/>
|
||||
<arg name="props" direction="out" type="a{sv}"/>
|
||||
</method>
|
||||
</interface>
|
||||
<interface name="org.xfce.Notifyd">
|
||||
<method name="Quit">
|
||||
</method>
|
||||
</interface-->
|
||||
<interface name="org.freedesktop.Notifications">
|
||||
<method name="GetServerInformation">
|
||||
<arg name="name" type="s" direction="out"/>
|
||||
<arg name="vendor" type="s" direction="out"/>
|
||||
<arg name="version" type="s" direction="out"/>
|
||||
<arg name="spec_version" type="s" direction="out"/>
|
||||
</method>
|
||||
<method name="CloseNotification">
|
||||
<arg name="id" type="u" direction="in"/>
|
||||
</method>
|
||||
<method name="Notify">
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.In6" value="QVariantMap"/>
|
||||
<arg name="app_name" type="s" direction="in"/>
|
||||
<arg name="replaces_id" type="u" direction="in"/>
|
||||
<arg name="app_icon" type="s" direction="in"/>
|
||||
<arg name="summary" type="s" direction="in"/>
|
||||
<arg name="body" type="s" direction="in"/>
|
||||
<arg name="actions" type="as" direction="in"/>
|
||||
<arg name="hints" type="a{sv}" direction="in"/>
|
||||
<arg name="expire_timeout" type="i" direction="in"/>
|
||||
<arg name="id" type="u" direction="out"/>
|
||||
</method>
|
||||
<method name="GetCapabilities">
|
||||
<arg name="capabilities" type="as" direction="out"/>
|
||||
</method>
|
||||
<signal name="ActionInvoked">
|
||||
<arg type="u"/>
|
||||
<arg type="s"/>
|
||||
</signal>
|
||||
<signal name="NotificationClosed">
|
||||
<arg type="u"/>
|
||||
<arg type="u"/>
|
||||
</signal>
|
||||
</interface>
|
||||
</node>
|
||||
|
@ -1,7 +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.SingleApplication">
|
||||
<method name="activateWindow">
|
||||
</method>
|
||||
</interface>
|
||||
</node>
|
@ -1,4 +0,0 @@
|
||||
/*! \mainpage A minimal shared library for LXQt DE.
|
||||
|
||||
liblxqt containing shared classes for LXQt developed by LXQt team and contributors.
|
||||
*/
|
@ -1,204 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright: 2012-2013 Razor team
|
||||
* Authors:
|
||||
* Petr Vanek <petr@scribus.info>
|
||||
*
|
||||
* This program or library is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
#include <QDir>
|
||||
|
||||
#include "lxqtapplication.h"
|
||||
#include "lxqtsettings.h"
|
||||
|
||||
#include <XdgDirs>
|
||||
|
||||
using namespace LXQt;
|
||||
|
||||
#define COLOR_DEBUG "\033[32;2m"
|
||||
#define COLOR_WARN "\033[33;2m"
|
||||
#define COLOR_CRITICAL "\033[31;1m"
|
||||
#define COLOR_FATAL "\033[33;1m"
|
||||
#define COLOR_RESET "\033[0m"
|
||||
|
||||
#define QAPP_NAME qApp ? qApp->objectName().toUtf8().constData() : ""
|
||||
|
||||
#include <cstdio>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#include <csignal>
|
||||
#include <cerrno>
|
||||
#include <sys/socket.h>
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
#include <QSocketNotifier>
|
||||
/*! \brief Log qDebug input to file
|
||||
Used only in pure Debug builds or when is the system environment
|
||||
variable LXQT_DEBUG set
|
||||
*/
|
||||
void dbgMessageOutput(QtMsgType type, const QMessageLogContext &ctx, const QString & msgStr)
|
||||
{
|
||||
Q_UNUSED(ctx)
|
||||
QByteArray msgBuf = msgStr.toUtf8();
|
||||
const char* msg = msgBuf.constData();
|
||||
QDir dir(XdgDirs::configHome().toUtf8() + QLatin1String("/lxqt"));
|
||||
dir.mkpath(".");
|
||||
|
||||
const char* typestr;
|
||||
const char* color;
|
||||
switch (type) {
|
||||
case QtDebugMsg:
|
||||
typestr = "Debug";
|
||||
color = COLOR_DEBUG;
|
||||
break;
|
||||
case QtWarningMsg:
|
||||
typestr = "Warning";
|
||||
color = COLOR_WARN;
|
||||
break;
|
||||
case QtFatalMsg:
|
||||
typestr = "Fatal";
|
||||
color = COLOR_FATAL;
|
||||
break;
|
||||
default: // QtCriticalMsg
|
||||
typestr = "Critical";
|
||||
color = COLOR_CRITICAL;
|
||||
}
|
||||
|
||||
QByteArray dt = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz").toUtf8();
|
||||
if (isatty(STDERR_FILENO))
|
||||
fprintf(stderr, "%s %s(%p) %s: %s%s\n", color, QAPP_NAME, static_cast<void *>(qApp), typestr, msg, COLOR_RESET);
|
||||
else
|
||||
fprintf(stderr, "%s(%p) %s: %s\n", QAPP_NAME, static_cast<void *>(qApp), typestr, msg);
|
||||
|
||||
FILE *f = fopen(dir.absoluteFilePath("debug.log").toUtf8().constData(), "a+");
|
||||
fprintf(f, "%s %s(%p) %s: %s\n", dt.constData(), QAPP_NAME, static_cast<void *>(qApp), typestr, msg);
|
||||
fclose(f);
|
||||
|
||||
if (type == QtFatalMsg)
|
||||
abort();
|
||||
}
|
||||
|
||||
Application::Application(int &argc, char** argv)
|
||||
: QApplication(argc, argv)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
qInstallMessageHandler(dbgMessageOutput);
|
||||
#else
|
||||
if (!qEnvironmentVariableIsSet("LXQT_DEBUG"))
|
||||
qInstallMessageHandler(dbgMessageOutput);
|
||||
#endif
|
||||
|
||||
setWindowIcon(QIcon(QString(LXQT_GRAPHICS_DIR) + "/lxqt_logo.png"));
|
||||
connect(Settings::globalSettings(), SIGNAL(lxqtThemeChanged()), this, SLOT(updateTheme()));
|
||||
updateTheme();
|
||||
}
|
||||
|
||||
Application::Application(int &argc, char** argv, bool handleQuitSignals)
|
||||
: Application(argc, argv)
|
||||
{
|
||||
if (handleQuitSignals)
|
||||
{
|
||||
QList<int> signo_list = {SIGINT, SIGTERM, SIGHUP};
|
||||
connect(this, &Application::unixSignal, [this, signo_list] (int signo)
|
||||
{
|
||||
if (signo_list.contains(signo))
|
||||
quit();
|
||||
});
|
||||
listenToUnixSignals(signo_list);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::updateTheme()
|
||||
{
|
||||
const QString styleSheetKey = QFileInfo(applicationFilePath()).fileName();
|
||||
setStyleSheet(lxqtTheme.qss(styleSheetKey));
|
||||
emit themeChanged();
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class SignalHandler
|
||||
{
|
||||
public:
|
||||
static void signalHandler(int signo)
|
||||
{
|
||||
const int ret = write(instance->mSignalSock[0], &signo, sizeof (int));
|
||||
if (sizeof (int) != ret)
|
||||
qCritical() << QStringLiteral("unable to write into socketpair, %1").arg(strerror(errno));
|
||||
}
|
||||
|
||||
public:
|
||||
template <class Lambda>
|
||||
SignalHandler(Application * app, Lambda signalEmitter)
|
||||
: mSignalSock{-1, -1}
|
||||
{
|
||||
if (0 != socketpair(AF_UNIX, SOCK_STREAM, 0, mSignalSock))
|
||||
{
|
||||
qCritical() << QStringLiteral("unable to create socketpair for correct signal handling: %1)").arg(strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
mNotifier.reset(new QSocketNotifier(mSignalSock[1], QSocketNotifier::Read));
|
||||
QObject::connect(mNotifier.data(), &QSocketNotifier::activated, app, [this, signalEmitter] {
|
||||
int signo = 0;
|
||||
int ret = read(mSignalSock[1], &signo, sizeof (int));
|
||||
if (sizeof (int) != ret)
|
||||
qCritical() << QStringLiteral("unable to read signal from socketpair, %1").arg(strerror(errno));
|
||||
signalEmitter(signo);
|
||||
});
|
||||
}
|
||||
|
||||
~SignalHandler()
|
||||
{
|
||||
close(mSignalSock[0]);
|
||||
close(mSignalSock[1]);
|
||||
}
|
||||
|
||||
void listenToSignals(QList<int> const & signoList)
|
||||
{
|
||||
struct sigaction sa;
|
||||
sa.sa_handler = signalHandler;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = 0;
|
||||
for (auto const & signo : signoList)
|
||||
sigaction(signo, &sa, nullptr);
|
||||
}
|
||||
|
||||
public:
|
||||
static QScopedPointer<SignalHandler> instance;
|
||||
|
||||
private:
|
||||
int mSignalSock[2];
|
||||
QScopedPointer<QSocketNotifier> mNotifier;
|
||||
};
|
||||
|
||||
QScopedPointer<SignalHandler> SignalHandler::instance;
|
||||
}
|
||||
|
||||
void Application::listenToUnixSignals(QList<int> const & signoList)
|
||||
{
|
||||
static QScopedPointer<QSocketNotifier> signal_notifier;
|
||||
|
||||
if (SignalHandler::instance.isNull())
|
||||
SignalHandler::instance.reset(new SignalHandler{this, [this] (int signo) { emit unixSignal(signo); }});
|
||||
SignalHandler::instance->listenToSignals(signoList);
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright: 2012-2013 Razor team
|
||||
* Authors:
|
||||
* Petr Vanek <petr@scribus.info>
|
||||
*
|
||||
* This program or library is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
#ifndef LXQTAPPLICATION_H
|
||||
#define LXQTAPPLICATION_H
|
||||
|
||||
#include <QApplication>
|
||||
#include <QProxyStyle>
|
||||
#include "lxqtglobals.h"
|
||||
|
||||
namespace LXQt
|
||||
{
|
||||
|
||||
/*! \brief LXQt wrapper around QApplication.
|
||||
* It loads various LXQt related stuff by default (window icon, icon theme...)
|
||||
*
|
||||
* \note This wrapper is intended to be used only inside LXQt project. Using it
|
||||
* in external application will automatically require linking to various
|
||||
* LXQt libraries.
|
||||
*
|
||||
*/
|
||||
class LXQT_API Application : public QApplication
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/*! Construct a LXQt application object.
|
||||
* \param argc standard argc as in QApplication
|
||||
* \param argv standard argv as in QApplication
|
||||
*/
|
||||
Application(int &argc, char **argv);
|
||||
/*! Construct a LXQt application object.
|
||||
* \param argc standard argc as in QApplication
|
||||
* \param argv standard argv as in QApplication
|
||||
* \param handleQuitSignals flag if signals SIGINT, SIGTERM, SIGHUP should be handled internaly (\sa quit() application)
|
||||
*/
|
||||
Application(int &argc, char **argv, bool handleQuitSignals);
|
||||
virtual ~Application() {}
|
||||
/*! Install UNIX signal handler for signals defined in \param signalList
|
||||
* Upon receiving of any of this signals the \sa unixSignal signal is emitted
|
||||
*/
|
||||
void listenToUnixSignals(QList<int> const & signolList);
|
||||
|
||||
private slots:
|
||||
void updateTheme();
|
||||
|
||||
signals:
|
||||
void themeChanged();
|
||||
/*! Signal is emitted upon receival of registered unix signal
|
||||
* \param signo the received unix signal number
|
||||
*/
|
||||
void unixSignal(int signo);
|
||||
};
|
||||
|
||||
#if defined(lxqtApp)
|
||||
#undef lxqtApp
|
||||
#endif
|
||||
#define lxqtApp (static_cast<LXQt::Application *>(qApp))
|
||||
|
||||
} // namespace LXQt
|
||||
#endif // LXQTAPPLICATION_H
|
@ -1,130 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright (C) 2012 Alec Moskvin <alecm@gmx.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
#include "lxqtautostartentry.h"
|
||||
#include <QFileInfo>
|
||||
|
||||
#include <XdgAutoStart>
|
||||
#include <XdgDirs>
|
||||
|
||||
using namespace LXQt;
|
||||
|
||||
AutostartEntry::AutostartEntry() :
|
||||
mLocalState(StateNone), mSystem(false)
|
||||
{
|
||||
}
|
||||
|
||||
AutostartEntry::AutostartEntry(const QString& name):
|
||||
mLocalState(StateNone), mSystem(false)
|
||||
{
|
||||
const QStringList& dirs = XdgDirs::autostartDirs();
|
||||
foreach (const QString& dir, dirs)
|
||||
{
|
||||
const QString path = QString("%1/%2").arg(dir, name);
|
||||
if (QFile(path).exists())
|
||||
{
|
||||
mSystemFile.load(path);
|
||||
mSystem = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const QString path = QString("%1/%2").arg(XdgDirs::autostartHome(), name);
|
||||
if (QFile(path).exists())
|
||||
{
|
||||
mLocalFile.load(path);
|
||||
mLocalState = StateExists;
|
||||
}
|
||||
}
|
||||
|
||||
void AutostartEntry::setFile(const XdgDesktopFile& file)
|
||||
{
|
||||
const bool local = isLocal();
|
||||
if (mSystem && local && file == mSystemFile)
|
||||
{
|
||||
removeLocal();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (local)
|
||||
mLocalState = StateModified;
|
||||
else
|
||||
mLocalState = StateTransient;
|
||||
mLocalFile = file;
|
||||
}
|
||||
}
|
||||
|
||||
bool AutostartEntry::removeLocal()
|
||||
{
|
||||
if (!isLocal())
|
||||
return false;
|
||||
|
||||
if (mLocalState == StateTransient)
|
||||
mLocalState = StateNone;
|
||||
else
|
||||
mLocalState = StateDeleted;
|
||||
|
||||
return !mSystem;
|
||||
}
|
||||
|
||||
const XdgDesktopFile& AutostartEntry::file() const
|
||||
{
|
||||
return isLocal() ? mLocalFile : mSystemFile;
|
||||
}
|
||||
|
||||
QString AutostartEntry::name() const
|
||||
{
|
||||
return QFileInfo(file().fileName()).fileName();
|
||||
}
|
||||
|
||||
void AutostartEntry::setEnabled(bool enable)
|
||||
{
|
||||
XdgDesktopFile f = file();
|
||||
if (enable)
|
||||
f.removeEntry("Hidden");
|
||||
else
|
||||
f.setValue("Hidden", true);
|
||||
|
||||
setFile(f);
|
||||
}
|
||||
|
||||
bool AutostartEntry::isEnabled() const
|
||||
{
|
||||
return !isEmpty() && !file().value("Hidden", false).toBool();
|
||||
}
|
||||
|
||||
bool AutostartEntry::commit()
|
||||
{
|
||||
if (mLocalState == StateDeleted)
|
||||
{
|
||||
mLocalState = StateNone;
|
||||
return QFile::remove(mLocalFile.fileName());
|
||||
}
|
||||
else if (mLocalState == StateModified || mLocalState == StateTransient)
|
||||
{
|
||||
mLocalState = StateExists;
|
||||
return mLocalFile.save(XdgAutoStart::localPath(mLocalFile));
|
||||
}
|
||||
return true;
|
||||
}
|
@ -1,114 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright (C) 2012 Alec Moskvin <alecm@gmx.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
#ifndef LXQTAUTOSTARTENTRY_H
|
||||
#define LXQTAUTOSTARTENTRY_H
|
||||
|
||||
#include "lxqtglobals.h"
|
||||
#include <XdgDesktopFile>
|
||||
|
||||
namespace LXQt
|
||||
{
|
||||
|
||||
/*! \brief The AutostartEntry class provides an interface for staging configuration of individual
|
||||
autostart items. All changes are made in memory until commit() is called.
|
||||
|
||||
- "system" file refers to a read-only file in /etc/xdg/autostart (or a directory in $XDG_CONFIG_DIRS)
|
||||
- "local" file refers to the file in user's ~/.config/autostart (or in $XDG_CONFIG_HOME/autostart)
|
||||
|
||||
When a "local" file has the same name as the "system" file, the local one overrides it. This class
|
||||
tries to ensure that the "local" file is deleted if it's identical to the "system" file.
|
||||
*/
|
||||
class LXQT_API AutostartEntry
|
||||
{
|
||||
public:
|
||||
/*! Constructs an AutostartEntry object for a specific entry.
|
||||
* \param name The name of the autostart desktop file (e.g. "lxqt-panel.desktop")
|
||||
*/
|
||||
AutostartEntry(const QString& name);
|
||||
|
||||
//! \brief Default constructor
|
||||
AutostartEntry();
|
||||
|
||||
//! Destructor
|
||||
virtual ~AutostartEntry() { }
|
||||
|
||||
//! Returns the "active" desktop file
|
||||
const XdgDesktopFile& file() const;
|
||||
|
||||
//! Returns the name of the autostart entry (e.g. "lxqt-panel.desktop")
|
||||
QString name() const;
|
||||
|
||||
/*! Sets to the specified desktop file. Use this to make modifications.
|
||||
* \param file The desktop file
|
||||
*/
|
||||
void setFile(const XdgDesktopFile& file);
|
||||
|
||||
/*! Sets whether the item auto-starts
|
||||
* \param enable When false, sets the "Hidden" key which will prevent the item from starting
|
||||
*/
|
||||
void setEnabled(bool enable);
|
||||
|
||||
//! Returns true if the item will auto-start
|
||||
bool isEnabled() const;
|
||||
|
||||
/*! Returns true if the entry does not exist, and the object carries no useful information
|
||||
* and can be ignored/deleted.
|
||||
*/
|
||||
bool isEmpty() const { return !mSystem && mLocalState == StateNone; }
|
||||
|
||||
/*! Write any changes to disk
|
||||
* \return true on success
|
||||
*/
|
||||
bool commit();
|
||||
|
||||
protected:
|
||||
//! Returns true if the user's "local" version exists
|
||||
bool isLocal() const { return mLocalState != StateNone && mLocalState != StateDeleted; }
|
||||
|
||||
/*! Removes the user's "local" version of the file, reverting to system defaults
|
||||
* \return true if there is no "system" version left (i.e. the entry was entirely deleted)
|
||||
*/
|
||||
bool removeLocal();
|
||||
|
||||
//! \brief a read-only file in /etc/xdg/autostart (or a directory in $XDG_CONFIG_DIRS)
|
||||
XdgDesktopFile mSystemFile;
|
||||
|
||||
//! \brief the file in user's ~/.config/autostart (or in $XDG_CONFIG_HOME/autostart)
|
||||
XdgDesktopFile mLocalFile;
|
||||
|
||||
//! State of the "local" file
|
||||
enum ItemState
|
||||
{
|
||||
StateNone, //! does not exist at all
|
||||
StateDeleted, //! needs to be deleted from disk
|
||||
StateTransient, //! does not yet exist on disk
|
||||
StateModified, //! exists on disk and is modified
|
||||
StateExists //! exists on disk and unmodified
|
||||
} mLocalState;
|
||||
bool mSystem; //! true if the "system" file exists
|
||||
};
|
||||
|
||||
} // namespace LXQt
|
||||
#endif // LXQTAUTOSTARTENTRY_H
|
@ -1,39 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright: 2013 - LXQt team
|
||||
* Authors:
|
||||
* Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
||||
*
|
||||
* This program or library is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
#ifndef _LXQT_GLOBALS_H_
|
||||
#define _LXQT_GLOBALS_H_
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
#ifdef COMPILE_LIBLXQT
|
||||
#define LXQT_API Q_DECL_EXPORT
|
||||
#else
|
||||
#define LXQT_API Q_DECL_IMPORT
|
||||
#endif
|
||||
|
||||
#endif // _LXQT_GLOBALS_H_
|
@ -1,695 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright: 2012 Razor team
|
||||
* Authors:
|
||||
* Alexander Sokoloff <sokoloff.a@gmail.com>
|
||||
*
|
||||
* This program or library is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
|
||||
#include "lxqtgridlayout.h"
|
||||
#include <QDebug>
|
||||
#include <math.h>
|
||||
#include <QWidget>
|
||||
#include <QVariantAnimation>
|
||||
|
||||
using namespace LXQt;
|
||||
|
||||
class LXQt::GridLayoutPrivate
|
||||
{
|
||||
public:
|
||||
GridLayoutPrivate();
|
||||
~GridLayoutPrivate();
|
||||
|
||||
QList<QLayoutItem*> mItems;
|
||||
int mRowCount;
|
||||
int mColumnCount;
|
||||
GridLayout::Direction mDirection;
|
||||
|
||||
bool mIsValid;
|
||||
QSize mCellSizeHint;
|
||||
QSize mCellMaxSize;
|
||||
int mVisibleCount;
|
||||
GridLayout::Stretch mStretch;
|
||||
bool mAnimate;
|
||||
int mAnimatedItems; //!< counter of currently animated items
|
||||
|
||||
|
||||
void updateCache();
|
||||
int rows() const;
|
||||
int cols() const;
|
||||
void setItemGeometry(QLayoutItem * item, QRect const & geometry);
|
||||
QSize mPrefCellMinSize;
|
||||
QSize mPrefCellMaxSize;
|
||||
QRect mOccupiedGeometry;
|
||||
};
|
||||
|
||||
namespace
|
||||
{
|
||||
class ItemMoveAnimation : public QVariantAnimation
|
||||
{
|
||||
public:
|
||||
static void animate(QLayoutItem * item, QRect const & geometry, LXQt::GridLayoutPrivate * layout)
|
||||
{
|
||||
ItemMoveAnimation* animation = new ItemMoveAnimation(item);
|
||||
animation->setStartValue(item->geometry());
|
||||
animation->setEndValue(geometry);
|
||||
++layout->mAnimatedItems;
|
||||
connect(animation, &QAbstractAnimation::finished, [layout] { --layout->mAnimatedItems; Q_ASSERT(0 <= layout->mAnimatedItems); });
|
||||
animation->start(DeleteWhenStopped);
|
||||
}
|
||||
|
||||
ItemMoveAnimation(QLayoutItem *item)
|
||||
: mItem(item)
|
||||
{
|
||||
setDuration(150);
|
||||
}
|
||||
|
||||
void updateCurrentValue(const QVariant ¤t)
|
||||
{
|
||||
mItem->setGeometry(current.toRect());
|
||||
}
|
||||
|
||||
private:
|
||||
QLayoutItem* mItem;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
GridLayoutPrivate::GridLayoutPrivate()
|
||||
{
|
||||
mColumnCount = 0;
|
||||
mRowCount = 0;
|
||||
mDirection = GridLayout::LeftToRight;
|
||||
mIsValid = false;
|
||||
mVisibleCount = 0;
|
||||
mStretch = GridLayout::StretchHorizontal | GridLayout::StretchVertical;
|
||||
mAnimate = false;
|
||||
mAnimatedItems = 0;
|
||||
mPrefCellMinSize = QSize(0,0);
|
||||
mPrefCellMaxSize = QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
|
||||
}
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
GridLayoutPrivate::~GridLayoutPrivate()
|
||||
{
|
||||
qDeleteAll(mItems);
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
void GridLayoutPrivate::updateCache()
|
||||
{
|
||||
mCellSizeHint = QSize(0, 0);
|
||||
mCellMaxSize = QSize(0, 0);
|
||||
mVisibleCount = 0;
|
||||
|
||||
const int N = mItems.count();
|
||||
for (int i=0; i < N; ++i)
|
||||
{
|
||||
QLayoutItem *item = mItems.at(i);
|
||||
if (!item->widget() || item->widget()->isHidden())
|
||||
continue;
|
||||
|
||||
int h = qBound(item->minimumSize().height(),
|
||||
item->sizeHint().height(),
|
||||
item->maximumSize().height());
|
||||
|
||||
int w = qBound(item->minimumSize().width(),
|
||||
item->sizeHint().width(),
|
||||
item->maximumSize().width());
|
||||
|
||||
mCellSizeHint.rheight() = qMax(mCellSizeHint.height(), h);
|
||||
mCellSizeHint.rwidth() = qMax(mCellSizeHint.width(), w);
|
||||
|
||||
mCellMaxSize.rheight() = qMax(mCellMaxSize.height(), item->maximumSize().height());
|
||||
mCellMaxSize.rwidth() = qMax(mCellMaxSize.width(), item->maximumSize().width());
|
||||
mVisibleCount++;
|
||||
|
||||
#if 0
|
||||
qDebug() << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-";
|
||||
qDebug() << "item.min" << item->minimumSize().width();
|
||||
qDebug() << "item.sz " << item->sizeHint().width();
|
||||
qDebug() << "item.max" << item->maximumSize().width();
|
||||
qDebug() << "w h" << w << h;
|
||||
qDebug() << "wid.sizeHint" << item->widget()->sizeHint();
|
||||
qDebug() << "mCellSizeHint:" << mCellSizeHint;
|
||||
qDebug() << "mCellMaxSize: " << mCellMaxSize;
|
||||
qDebug() << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-";
|
||||
#endif
|
||||
|
||||
}
|
||||
mCellSizeHint.rwidth() = qBound(mPrefCellMinSize.width(), mCellSizeHint.width(), mPrefCellMaxSize.width());
|
||||
mCellSizeHint.rheight()= qBound(mPrefCellMinSize.height(), mCellSizeHint.height(), mPrefCellMaxSize.height());
|
||||
mIsValid = !mCellSizeHint.isEmpty();
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
int GridLayoutPrivate::rows() const
|
||||
{
|
||||
if (mRowCount)
|
||||
return mRowCount;
|
||||
|
||||
if (!mColumnCount)
|
||||
return 1;
|
||||
|
||||
return ceil(mVisibleCount * 1.0 / mColumnCount);
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
int GridLayoutPrivate::cols() const
|
||||
{
|
||||
if (mColumnCount)
|
||||
return mColumnCount;
|
||||
|
||||
int rows = mRowCount;
|
||||
if (!rows)
|
||||
rows = 1;
|
||||
|
||||
return ceil(mVisibleCount * 1.0 / rows);
|
||||
}
|
||||
|
||||
void GridLayoutPrivate::setItemGeometry(QLayoutItem * item, QRect const & geometry)
|
||||
{
|
||||
mOccupiedGeometry |= geometry;
|
||||
if (mAnimate)
|
||||
{
|
||||
ItemMoveAnimation::animate(item, geometry, this);
|
||||
} else
|
||||
{
|
||||
item->setGeometry(geometry);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
GridLayout::GridLayout(QWidget *parent):
|
||||
QLayout(parent),
|
||||
d_ptr(new GridLayoutPrivate())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
GridLayout::~GridLayout()
|
||||
{
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
void GridLayout::addItem(QLayoutItem *item)
|
||||
{
|
||||
d_ptr->mItems.append(item);
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
QLayoutItem *GridLayout::itemAt(int index) const
|
||||
{
|
||||
Q_D(const GridLayout);
|
||||
if (index < 0 || index >= d->mItems.count())
|
||||
return 0;
|
||||
|
||||
return d->mItems.at(index);
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
QLayoutItem *GridLayout::takeAt(int index)
|
||||
{
|
||||
Q_D(GridLayout);
|
||||
if (index < 0 || index >= d->mItems.count())
|
||||
return 0;
|
||||
|
||||
QLayoutItem *item = d->mItems.takeAt(index);
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
int GridLayout::count() const
|
||||
{
|
||||
Q_D(const GridLayout);
|
||||
return d->mItems.count();
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
void GridLayout::invalidate()
|
||||
{
|
||||
Q_D(GridLayout);
|
||||
d->mIsValid = false;
|
||||
QLayout::invalidate();
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
int GridLayout::rowCount() const
|
||||
{
|
||||
Q_D(const GridLayout);
|
||||
return d->mRowCount;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
void GridLayout::setRowCount(int value)
|
||||
{
|
||||
Q_D(GridLayout);
|
||||
if (d->mRowCount != value)
|
||||
{
|
||||
d->mRowCount = value;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
int GridLayout::columnCount() const
|
||||
{
|
||||
Q_D(const GridLayout);
|
||||
return d->mColumnCount;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
void GridLayout::setColumnCount(int value)
|
||||
{
|
||||
Q_D(GridLayout);
|
||||
if (d->mColumnCount != value)
|
||||
{
|
||||
d->mColumnCount = value;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
GridLayout::Direction GridLayout::direction() const
|
||||
{
|
||||
Q_D(const GridLayout);
|
||||
return d->mDirection;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
void GridLayout::setDirection(GridLayout::Direction value)
|
||||
{
|
||||
Q_D(GridLayout);
|
||||
if (d->mDirection != value)
|
||||
{
|
||||
d->mDirection = value;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
GridLayout::Stretch GridLayout::stretch() const
|
||||
{
|
||||
Q_D(const GridLayout);
|
||||
return d->mStretch;
|
||||
}
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
void GridLayout::setStretch(Stretch value)
|
||||
{
|
||||
Q_D(GridLayout);
|
||||
if (d->mStretch != value)
|
||||
{
|
||||
d->mStretch = value;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
void GridLayout::moveItem(int from, int to, bool withAnimation /*= false*/)
|
||||
{
|
||||
Q_D(GridLayout);
|
||||
d->mAnimate = withAnimation;
|
||||
d->mItems.move(from, to);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
bool GridLayout::animatedMoveInProgress() const
|
||||
{
|
||||
Q_D(const GridLayout);
|
||||
return 0 < d->mAnimatedItems;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
QSize GridLayout::cellMinimumSize() const
|
||||
{
|
||||
Q_D(const GridLayout);
|
||||
return d->mPrefCellMinSize;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
void GridLayout::setCellMinimumSize(QSize minSize)
|
||||
{
|
||||
Q_D(GridLayout);
|
||||
if (d->mPrefCellMinSize != minSize)
|
||||
{
|
||||
d->mPrefCellMinSize = minSize;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
void GridLayout::setCellMinimumHeight(int value)
|
||||
{
|
||||
Q_D(GridLayout);
|
||||
if (d->mPrefCellMinSize.height() != value)
|
||||
{
|
||||
d->mPrefCellMinSize.setHeight(value);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
void GridLayout::setCellMinimumWidth(int value)
|
||||
{
|
||||
Q_D(GridLayout);
|
||||
if (d->mPrefCellMinSize.width() != value)
|
||||
{
|
||||
d->mPrefCellMinSize.setWidth(value);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
QSize GridLayout::cellMaximumSize() const
|
||||
{
|
||||
Q_D(const GridLayout);
|
||||
return d->mPrefCellMaxSize;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
void GridLayout::setCellMaximumSize(QSize maxSize)
|
||||
{
|
||||
Q_D(GridLayout);
|
||||
if (d->mPrefCellMaxSize != maxSize)
|
||||
{
|
||||
d->mPrefCellMaxSize = maxSize;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
void GridLayout::setCellMaximumHeight(int value)
|
||||
{
|
||||
Q_D(GridLayout);
|
||||
if (d->mPrefCellMaxSize.height() != value)
|
||||
{
|
||||
d->mPrefCellMaxSize.setHeight(value);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
void GridLayout::setCellMaximumWidth(int value)
|
||||
{
|
||||
Q_D(GridLayout);
|
||||
if (d->mPrefCellMaxSize.width() != value)
|
||||
{
|
||||
d->mPrefCellMaxSize.setWidth(value);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
void GridLayout::setCellFixedSize(QSize size)
|
||||
{
|
||||
Q_D(GridLayout);
|
||||
if (d->mPrefCellMinSize != size ||
|
||||
d->mPrefCellMaxSize != size)
|
||||
{
|
||||
d->mPrefCellMinSize = size;
|
||||
d->mPrefCellMaxSize = size;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
void GridLayout::setCellFixedHeight(int value)
|
||||
{
|
||||
Q_D(GridLayout);
|
||||
if (d->mPrefCellMinSize.height() != value ||
|
||||
d->mPrefCellMaxSize.height() != value)
|
||||
{
|
||||
d->mPrefCellMinSize.setHeight(value);
|
||||
d->mPrefCellMaxSize.setHeight(value);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
void GridLayout::setCellFixedWidth(int value)
|
||||
{
|
||||
Q_D(GridLayout);
|
||||
if (d->mPrefCellMinSize.width() != value ||
|
||||
d->mPrefCellMaxSize.width() != value)
|
||||
{
|
||||
d->mPrefCellMinSize.setWidth(value);
|
||||
d->mPrefCellMaxSize.setWidth(value);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
QSize GridLayout::sizeHint() const
|
||||
{
|
||||
Q_D(const GridLayout);
|
||||
|
||||
if (!d->mIsValid)
|
||||
const_cast<GridLayoutPrivate*>(d)->updateCache();
|
||||
|
||||
return QSize(d->cols() * d->mCellSizeHint.width(),
|
||||
d->rows() * d->mCellSizeHint.height());
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
void GridLayout::setGeometry(const QRect &geometry)
|
||||
{
|
||||
Q_D(GridLayout);
|
||||
|
||||
const bool visual_h_reversed = parentWidget() && parentWidget()->isRightToLeft();
|
||||
|
||||
QLayout::setGeometry(geometry);
|
||||
const QPoint occupied_start = visual_h_reversed ? geometry.topRight() : geometry.topLeft();
|
||||
d->mOccupiedGeometry.setTopLeft(occupied_start);
|
||||
d->mOccupiedGeometry.setBottomRight(occupied_start);
|
||||
|
||||
if (!d->mIsValid)
|
||||
d->updateCache();
|
||||
|
||||
int y = geometry.top();
|
||||
int x = geometry.left();
|
||||
|
||||
// For historical reasons QRect::right returns left() + width() - 1
|
||||
// and QRect::bottom() returns top() + height() - 1;
|
||||
// So we use left() + height() and top() + height()
|
||||
//
|
||||
// http://qt-project.org/doc/qt-4.8/qrect.html
|
||||
|
||||
const int maxX = geometry.left() + geometry.width();
|
||||
const int maxY = geometry.top() + geometry.height();
|
||||
|
||||
const bool stretch_h = d->mStretch.testFlag(StretchHorizontal);
|
||||
const bool stretch_v = d->mStretch.testFlag(StretchVertical);
|
||||
|
||||
const int cols = d->cols();
|
||||
int itemWidth = 0;
|
||||
if (stretch_h && 0 < cols)
|
||||
itemWidth = qMin(geometry.width() / cols, d->mCellMaxSize.width());
|
||||
else
|
||||
itemWidth = d->mCellSizeHint.width();
|
||||
itemWidth = qBound(qMin(d->mPrefCellMinSize.width(), maxX), itemWidth, d->mPrefCellMaxSize.width());
|
||||
const int widthRemain = stretch_h && 0 < itemWidth ? geometry.width() % itemWidth : 0;
|
||||
|
||||
const int rows = d->rows();
|
||||
int itemHeight = 0;
|
||||
if (stretch_v && 0 < rows)
|
||||
itemHeight = qMin(geometry.height() / rows, d->mCellMaxSize.height());
|
||||
else
|
||||
itemHeight = d->mCellSizeHint.height();
|
||||
itemHeight = qBound(qMin(d->mPrefCellMinSize.height(), maxY), itemHeight, d->mPrefCellMaxSize.height());
|
||||
const int heightRemain = stretch_v && 0 < itemHeight ? geometry.height() % itemHeight : 0;
|
||||
|
||||
#if 0
|
||||
qDebug() << "** GridLayout::setGeometry *******************************";
|
||||
qDebug() << "Geometry:" << geometry;
|
||||
qDebug() << "CellSize:" << d->mCellSizeHint;
|
||||
qDebug() << "Constraints:" << "min" << d->mPrefCellMinSize << "max" << d->mPrefCellMaxSize;
|
||||
qDebug() << "Count" << count();
|
||||
qDebug() << "Cols:" << d->cols() << "(" << d->mColumnCount << ")";
|
||||
qDebug() << "Rows:" << d->rows() << "(" << d->mRowCount << ")";
|
||||
qDebug() << "Stretch:" << "h:" << (d->mStretch.testFlag(StretchHorizontal)) << " v:" << (d->mStretch.testFlag(StretchVertical));
|
||||
qDebug() << "Item:" << "h:" << itemHeight << " w:" << itemWidth;
|
||||
#endif
|
||||
|
||||
int remain_height = heightRemain;
|
||||
int remain_width = widthRemain;
|
||||
if (d->mDirection == LeftToRight)
|
||||
{
|
||||
int height = itemHeight + (0 < remain_height-- ? 1 : 0);
|
||||
foreach(QLayoutItem *item, d->mItems)
|
||||
{
|
||||
if (!item->widget() || item->widget()->isHidden())
|
||||
continue;
|
||||
int width = itemWidth + (0 < remain_width-- ? 1 : 0);
|
||||
|
||||
if (x + width > maxX)
|
||||
{
|
||||
x = geometry.left();
|
||||
y += height;
|
||||
|
||||
height = itemHeight + (0 < remain_height-- ? 1 : 0);
|
||||
remain_width = widthRemain;
|
||||
}
|
||||
|
||||
const int left = visual_h_reversed ? geometry.left() + geometry.right() - x - width + 1 : x;
|
||||
d->setItemGeometry(item, QRect(left, y, width, height));
|
||||
x += width;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int width = itemWidth + (0 < remain_width-- ? 1 : 0);
|
||||
foreach(QLayoutItem *item, d->mItems)
|
||||
{
|
||||
if (!item->widget() || item->widget()->isHidden())
|
||||
continue;
|
||||
int height = itemHeight + (0 < remain_height-- ? 1 : 0);
|
||||
|
||||
if (y + height > maxY)
|
||||
{
|
||||
y = geometry.top();
|
||||
x += width;
|
||||
|
||||
width = itemWidth + (0 < remain_width-- ? 1 : 0);
|
||||
remain_height = heightRemain;
|
||||
}
|
||||
const int left = visual_h_reversed ? geometry.left() + geometry.right() - x - width + 1 : x;
|
||||
d->setItemGeometry(item, QRect(left, y, width, height));
|
||||
y += height;
|
||||
}
|
||||
}
|
||||
d->mAnimate = false;
|
||||
}
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
QRect GridLayout::occupiedGeometry() const
|
||||
{
|
||||
return d_func()->mOccupiedGeometry;
|
||||
}
|
@ -1,245 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright: 2012 Razor team
|
||||
* Authors:
|
||||
* Alexander Sokoloff <sokoloff.a@gmail.com>
|
||||
*
|
||||
* This program or library is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
|
||||
#ifndef LXQTGRIDLAYOUT_H
|
||||
#define LXQTGRIDLAYOUT_H
|
||||
|
||||
#include <QList>
|
||||
#include "lxqtglobals.h"
|
||||
#include <QLayout>
|
||||
|
||||
|
||||
namespace LXQt
|
||||
{
|
||||
|
||||
class GridLayoutPrivate;
|
||||
|
||||
/**
|
||||
The GridLayout class lays out widgets in a grid.
|
||||
**/
|
||||
class LXQT_API GridLayout: public QLayout
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
This enum type is used to describe direction for this grid.
|
||||
**/
|
||||
enum Direction
|
||||
{
|
||||
LeftToRight, ///< The items are first laid out horizontally and then vertically.
|
||||
TopToBottom ///< The items are first laid out vertically and then horizontally.
|
||||
};
|
||||
|
||||
/**
|
||||
This enum type is used to describe stretch. It contains one horizontal
|
||||
and one vertical flags that can be combined to produce the required effect.
|
||||
*/
|
||||
enum StretchFlag
|
||||
{
|
||||
NoStretch = 0, ///< No justifies items
|
||||
StretchHorizontal = 1, ///< Justifies items in the available horizontal space
|
||||
StretchVertical = 2 ///< Justifies items in the available vertical space
|
||||
};
|
||||
Q_DECLARE_FLAGS(Stretch, StretchFlag)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Constructs a new GridLayout with parent widget, parent.
|
||||
The layout has one row and zero column initially, and will
|
||||
expand to left when new items are inserted.
|
||||
**/
|
||||
explicit GridLayout(QWidget *parent = 0);
|
||||
|
||||
/**
|
||||
Destroys the grid layout. The layout's widgets aren't destroyed.
|
||||
**/
|
||||
~GridLayout();
|
||||
|
||||
void addItem(QLayoutItem *item);
|
||||
QLayoutItem *itemAt(int index) const;
|
||||
QLayoutItem *takeAt(int index);
|
||||
int count() const;
|
||||
void invalidate();
|
||||
|
||||
QSize sizeHint() const;
|
||||
void setGeometry(const QRect &geometry);
|
||||
QRect occupiedGeometry() const;
|
||||
|
||||
|
||||
/**
|
||||
Returns the number of rows in this grid.
|
||||
**/
|
||||
int rowCount() const;
|
||||
|
||||
/**
|
||||
Sets the number of rows in this grid. If value is 0, then rows
|
||||
count will calculated automatically when new items are inserted.
|
||||
|
||||
In the most cases you should to set fixed number for one thing,
|
||||
or for rows, or for columns.
|
||||
|
||||
\sa GridLayout::setColumnCount
|
||||
**/
|
||||
void setRowCount(int value);
|
||||
|
||||
|
||||
/**
|
||||
Returns the number of columns in this grid.
|
||||
**/
|
||||
int columnCount() const;
|
||||
|
||||
/**
|
||||
Sets the number of columns in this grid. If value is 0, then columns
|
||||
count will calculated automatically when new items are inserted.
|
||||
|
||||
In the most cases you should to set fixed number for one thing,
|
||||
or for rows, or for columns.
|
||||
|
||||
\sa GridLayout::setRowCount
|
||||
**/
|
||||
void setColumnCount(int value);
|
||||
|
||||
|
||||
/**
|
||||
Returns the alignment of this grid.
|
||||
|
||||
\sa GridLayout::Direction
|
||||
**/
|
||||
Direction direction() const;
|
||||
|
||||
/**
|
||||
Sets the direction for this grid.
|
||||
|
||||
\sa GridLayout::Direction
|
||||
**/
|
||||
void setDirection(Direction value);
|
||||
|
||||
/**
|
||||
Returns the stretch flags of this grid.
|
||||
|
||||
\sa GridLayout::StretchFlag
|
||||
**/
|
||||
Stretch stretch() const;
|
||||
|
||||
/**
|
||||
Sets the stretch flags for this grid.
|
||||
|
||||
\sa GridLayout::StretchFlag
|
||||
**/
|
||||
void setStretch(Stretch value);
|
||||
|
||||
/**
|
||||
Moves the item at index position \param from to index position \param to.
|
||||
If \param withAnimation set the reordering will be animated
|
||||
**/
|
||||
void moveItem(int from, int to, bool withAnimation = false);
|
||||
|
||||
/**
|
||||
Checks if layout is currently animated after the \sa moveItem()
|
||||
invocation.
|
||||
**/
|
||||
bool animatedMoveInProgress() const;
|
||||
|
||||
/**
|
||||
Returns the cells' minimum size.
|
||||
By default, this property contains a size with zero width and height.
|
||||
**/
|
||||
QSize cellMinimumSize() const;
|
||||
|
||||
/**
|
||||
Sets the minimum size of all cells to minSize pixels.
|
||||
**/
|
||||
void setCellMinimumSize(QSize minSize);
|
||||
|
||||
/**
|
||||
Sets the minimum height of the cells to value without
|
||||
changing the width. Provided for convenience.
|
||||
**/
|
||||
void setCellMinimumHeight(int value);
|
||||
|
||||
/**
|
||||
Sets the minimum width of the cells to value without
|
||||
changing the heights. Provided for convenience.
|
||||
**/
|
||||
void setCellMinimumWidth(int value);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Returns the cells' maximum size.
|
||||
By default, this property contains a size with zero width and height.
|
||||
**/
|
||||
QSize cellMaximumSize() const;
|
||||
|
||||
/**
|
||||
Sets the maximum size of all cells to maxSize pixels.
|
||||
**/
|
||||
void setCellMaximumSize(QSize maxSize);
|
||||
|
||||
/**
|
||||
Sets the maximum height of the cells to value without
|
||||
changing the width. Provided for convenience.
|
||||
**/
|
||||
void setCellMaximumHeight(int value);
|
||||
|
||||
/**
|
||||
Sets the maximum width of the cells to value without
|
||||
changing the heights. Provided for convenience.
|
||||
**/
|
||||
void setCellMaximumWidth(int value);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Sets both the minimum and maximum sizes of the cells to size,
|
||||
thereby preventing it from ever growing or shrinking.
|
||||
**/
|
||||
void setCellFixedSize(QSize size);
|
||||
|
||||
/**
|
||||
Sets both the minimum and maximum height of the cells to value without
|
||||
changing the width. Provided for convenience.
|
||||
**/
|
||||
void setCellFixedHeight(int value);
|
||||
|
||||
/**
|
||||
Sets both the minimum and maximum width of the cells to value without
|
||||
changing the heights. Provided for convenience.
|
||||
**/
|
||||
void setCellFixedWidth(int value);
|
||||
|
||||
private:
|
||||
GridLayoutPrivate* const d_ptr;
|
||||
Q_DECLARE_PRIVATE(GridLayout)
|
||||
};
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(GridLayout::Stretch)
|
||||
|
||||
} // namespace LXQt
|
||||
#endif // LXQTGRIDLAYOUT_H
|
@ -1,127 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://lxqt.org
|
||||
*
|
||||
* Copyright: 2010-2011 Razor team
|
||||
* Authors:
|
||||
* Alexander Sokoloff <sokoloff.a@gmail.com>
|
||||
* Paulo Lieuthier <paulolieuthier@gmail.com>
|
||||
*
|
||||
* This program or library is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
#include "lxqthtmldelegate.h"
|
||||
#include <QAbstractTextDocumentLayout>
|
||||
#include <QTextDocument>
|
||||
|
||||
using namespace LXQt;
|
||||
|
||||
|
||||
HtmlDelegate::HtmlDelegate(const QSize iconSize, QObject* parent) :
|
||||
QStyledItemDelegate(parent),
|
||||
mIconSize(iconSize)
|
||||
{
|
||||
}
|
||||
|
||||
HtmlDelegate::~HtmlDelegate()
|
||||
{
|
||||
}
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
void HtmlDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
QStyleOptionViewItem options = option;
|
||||
initStyleOption(&options, index);
|
||||
const bool is_right_to_left = Qt::RightToLeft == options.direction;
|
||||
|
||||
painter->save();
|
||||
|
||||
QTextDocument doc;
|
||||
doc.setHtml(options.text);
|
||||
QIcon icon = options.icon;
|
||||
|
||||
options.text = QString();
|
||||
options.icon = QIcon();
|
||||
|
||||
// icon size
|
||||
const QSize iconSize = icon.actualSize(mIconSize);
|
||||
QRect iconRect = QRect(8, 8, iconSize.width(), iconSize.height());
|
||||
if (is_right_to_left)
|
||||
{
|
||||
iconRect.moveLeft(options.rect.left() + options.rect.right() - iconRect.x() - iconRect.width() + 1);
|
||||
}
|
||||
|
||||
// set doc size
|
||||
doc.setTextWidth(options.rect.width() - iconRect.width() - 8);
|
||||
|
||||
options.widget->style()->drawControl(QStyle::CE_ItemViewItem, &options, painter);
|
||||
|
||||
// paint icon
|
||||
painter->translate(options.rect.left(), options.rect.top());
|
||||
icon.paint(painter, iconRect);
|
||||
|
||||
if (!is_right_to_left)
|
||||
{
|
||||
// shift text right to make icon visible
|
||||
painter->translate(iconRect.right() + 8, 0);
|
||||
}
|
||||
const QRect clip(0, 0, options.rect.width() - iconRect.width() - 8, options.rect.height());
|
||||
painter->setClipRect(clip);
|
||||
|
||||
// set text color to red for selected item
|
||||
QAbstractTextDocumentLayout::PaintContext ctx;
|
||||
if (option.state & QStyle::State_Selected)
|
||||
{
|
||||
QPalette::ColorGroup colorGroup = (option.state & QStyle::State_Active) ? QPalette::Active : QPalette::Inactive;
|
||||
ctx.palette.setColor(QPalette::Text, option.palette.color(colorGroup, QPalette::HighlightedText));
|
||||
}
|
||||
|
||||
ctx.clip = clip;
|
||||
doc.documentLayout()->draw(painter, ctx);
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
QSize HtmlDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||
{
|
||||
QStyleOptionViewItem options = option;
|
||||
initStyleOption(&options, index);
|
||||
|
||||
const QSize iconSize = options.icon.actualSize(mIconSize);
|
||||
const QRect iconRect = QRect(8, 8, iconSize.width(), iconSize.height());
|
||||
const QSize optSize = options.rect.size();
|
||||
|
||||
QTextDocument doc;
|
||||
doc.setHtml(options.text);
|
||||
|
||||
if (optSize.width() > 0)
|
||||
doc.setTextWidth(optSize.width() - iconRect.right() - 8);
|
||||
doc.adjustSize();
|
||||
return QSize(0 < optSize.width() ? optSize.width() : iconRect.width() + 8 + qRound(doc.size().width())
|
||||
, qMax(qRound(doc.size().height()), iconSize.height()) + 8);
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://lxqt.org
|
||||
*
|
||||
* Copyright: 2010-2011 Razor team
|
||||
* Authors:
|
||||
* Alexander Sokoloff <sokoloff.a@gmail.com>
|
||||
* Paulo Lieuthier <paulolieuthier@gmail.com>
|
||||
*
|
||||
* This program or library is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
#ifndef LXQTHTMLDELEGATE_H
|
||||
#define LXQTHTMLDELEGATE_H
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QPainter>
|
||||
#include "lxqtglobals.h"
|
||||
|
||||
namespace LXQt
|
||||
{
|
||||
|
||||
class LXQT_API HtmlDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit HtmlDelegate(const QSize iconSize, QObject* parent = 0);
|
||||
virtual ~HtmlDelegate();
|
||||
|
||||
virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
||||
|
||||
virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
||||
|
||||
private:
|
||||
QSize mIconSize;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,211 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright (C) 2012 Alec Moskvin <alecm@gmx.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
#include "lxqtnotification.h"
|
||||
#include "lxqtnotification_p.h"
|
||||
#include <QMessageBox>
|
||||
#include <QDebug>
|
||||
|
||||
using namespace LXQt;
|
||||
|
||||
Notification::Notification(const QString& summary, QObject* parent) :
|
||||
QObject(parent),
|
||||
d_ptr(new NotificationPrivate(summary, this))
|
||||
{
|
||||
}
|
||||
|
||||
Notification::~Notification()
|
||||
{
|
||||
Q_D(Notification);
|
||||
delete d;
|
||||
}
|
||||
|
||||
void Notification::update()
|
||||
{
|
||||
Q_D(Notification);
|
||||
d->update();
|
||||
}
|
||||
|
||||
void Notification::close()
|
||||
{
|
||||
Q_D(Notification);
|
||||
d->close();
|
||||
}
|
||||
|
||||
void Notification::setSummary(const QString& summary)
|
||||
{
|
||||
Q_D(Notification);
|
||||
d->mSummary = summary;
|
||||
}
|
||||
|
||||
void Notification::setBody(const QString& body)
|
||||
{
|
||||
Q_D(Notification);
|
||||
d->mBody = body;
|
||||
}
|
||||
|
||||
void Notification::setIcon(const QString& iconName)
|
||||
{
|
||||
Q_D(Notification);
|
||||
d->mIconName = iconName;
|
||||
}
|
||||
|
||||
void Notification::setActions(const QStringList& actions, int defaultAction)
|
||||
{
|
||||
Q_D(Notification);
|
||||
d->setActions(actions, defaultAction);
|
||||
}
|
||||
|
||||
void Notification::setTimeout(int timeout)
|
||||
{
|
||||
Q_D(Notification);
|
||||
d->mTimeout = timeout;
|
||||
}
|
||||
|
||||
void Notification::setHint(const QString& hintName, const QVariant& value)
|
||||
{
|
||||
Q_D(Notification);
|
||||
d->mHints.insert(hintName, value);
|
||||
}
|
||||
|
||||
void Notification::setUrgencyHint(Urgency urgency)
|
||||
{
|
||||
Q_D(Notification);
|
||||
d->mHints.insert("urgency", qvariant_cast<uchar>(urgency));
|
||||
}
|
||||
|
||||
void Notification::clearHints()
|
||||
{
|
||||
Q_D(Notification);
|
||||
d->mHints.clear();
|
||||
}
|
||||
|
||||
QStringList Notification::getCapabilities()
|
||||
{
|
||||
Q_D(Notification);
|
||||
return d->mInterface->GetCapabilities().value();
|
||||
}
|
||||
|
||||
const Notification::ServerInfo Notification::serverInfo()
|
||||
{
|
||||
Q_D(Notification);
|
||||
return d->serverInfo();
|
||||
}
|
||||
|
||||
void Notification::notify(const QString& summary, const QString& body, const QString& iconName)
|
||||
{
|
||||
Notification notification(summary);
|
||||
notification.setBody(body);
|
||||
notification.setIcon(iconName);
|
||||
notification.update();
|
||||
}
|
||||
|
||||
NotificationPrivate::NotificationPrivate(const QString& summary, Notification* parent) :
|
||||
mId(0),
|
||||
mSummary(summary),
|
||||
mTimeout(-1),
|
||||
q_ptr(parent)
|
||||
{
|
||||
mInterface = new OrgFreedesktopNotificationsInterface("org.freedesktop.Notifications",
|
||||
"/org/freedesktop/Notifications",
|
||||
QDBusConnection::sessionBus(), this);
|
||||
connect(mInterface, SIGNAL(NotificationClosed(uint, uint)), this, SLOT(notificationClosed(uint,uint)));
|
||||
connect(mInterface, SIGNAL(ActionInvoked(uint,QString)), this, SLOT(handleAction(uint,QString)));
|
||||
}
|
||||
|
||||
NotificationPrivate::~NotificationPrivate()
|
||||
{
|
||||
}
|
||||
|
||||
void NotificationPrivate::update()
|
||||
{
|
||||
QDBusPendingReply<uint> reply = mInterface->Notify(qAppName(), mId, mIconName, mSummary, mBody, mActions, mHints, mTimeout);
|
||||
reply.waitForFinished();
|
||||
if (!reply.isError())
|
||||
{
|
||||
mId = reply.value();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mHints.contains("urgency") && mHints.value("urgency").toInt() != Notification::UrgencyLow)
|
||||
QMessageBox::information(0, tr("Notifications Fallback"), mSummary + " \n\n " + mBody);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void NotificationPrivate::setActions(QStringList actions, int defaultAction)
|
||||
{
|
||||
mActions.clear();
|
||||
mDefaultAction = defaultAction;
|
||||
const int N = actions.size();
|
||||
for (int ix = 0; ix < N; ix++)
|
||||
{
|
||||
if (ix == defaultAction)
|
||||
mActions.append("default");
|
||||
else
|
||||
mActions.append(QString::number(ix));
|
||||
mActions.append(actions[ix]);
|
||||
}
|
||||
}
|
||||
|
||||
const Notification::ServerInfo NotificationPrivate::serverInfo()
|
||||
{
|
||||
Notification::ServerInfo info;
|
||||
info.name = mInterface->GetServerInformation(info.vendor, info.version, info.specVersion);
|
||||
return info;
|
||||
}
|
||||
|
||||
void NotificationPrivate::handleAction(uint id, QString key)
|
||||
{
|
||||
if (id != mId)
|
||||
return;
|
||||
|
||||
Q_Q(Notification);
|
||||
qDebug() << "action invoked:" << key;
|
||||
bool ok = true;
|
||||
int keyId;
|
||||
if (key == "default")
|
||||
keyId = mDefaultAction;
|
||||
else
|
||||
keyId = key.toInt(&ok);
|
||||
|
||||
if (ok && keyId >= 0)
|
||||
emit q->actionActivated(keyId);
|
||||
}
|
||||
|
||||
void NotificationPrivate::close()
|
||||
{
|
||||
mInterface->CloseNotification(mId);
|
||||
mId = 0;
|
||||
}
|
||||
|
||||
void NotificationPrivate::notificationClosed(uint id, uint reason)
|
||||
{
|
||||
Q_Q(Notification);
|
||||
if (id != 0 && id == mId)
|
||||
{
|
||||
mId = 0;
|
||||
}
|
||||
emit q->notificationClosed(Notification::CloseReason(reason));
|
||||
}
|
@ -1,193 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright (C) 2012 Alec Moskvin <alecm@gmx.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
#ifndef LXQTNOTIFICATION_H
|
||||
#define LXQTNOTIFICATION_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
#include "lxqtglobals.h"
|
||||
|
||||
namespace LXQt
|
||||
{
|
||||
|
||||
class NotificationPrivate;
|
||||
|
||||
/**
|
||||
* \brief Libnotify-style desktop notifications
|
||||
*
|
||||
* Spec: http://developer.gnome.org/notification-spec
|
||||
*/
|
||||
class LXQT_API Notification : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/*!
|
||||
* \brief Notification is an object that represents a single notification.
|
||||
* \param summary Summary text briefly describing the notification (required by the spec)
|
||||
*/
|
||||
Notification(const QString& summary = QString(), QObject* parent = 0);
|
||||
~Notification();
|
||||
|
||||
enum CloseReason
|
||||
{
|
||||
//! The notification expired.
|
||||
Expired = 1,
|
||||
//! The notification was dismissed by the user.
|
||||
Dismissed = 2,
|
||||
//! The notification was closed by a call to close().
|
||||
ForceClosed = 3,
|
||||
//! Undefined/reserved reasons.
|
||||
Unknown = 4
|
||||
};
|
||||
|
||||
enum Urgency
|
||||
{
|
||||
UrgencyLow = 0,
|
||||
UrgencyNormal = 1,
|
||||
UrgencyCritical = 2
|
||||
};
|
||||
|
||||
struct ServerInfo
|
||||
{
|
||||
//! The product name of the server.
|
||||
QString name;
|
||||
//! The vendor name. For example, "lxde-qt.org"
|
||||
QString vendor;
|
||||
//! The server's version number.
|
||||
QString version;
|
||||
//! The specification version the server is compliant with.
|
||||
QString specVersion;
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Set the summary text briefly describing the notification
|
||||
*/
|
||||
void setSummary(const QString& summary);
|
||||
|
||||
/*!
|
||||
* \brief Set the detailed body text
|
||||
*/
|
||||
void setBody(const QString& body);
|
||||
|
||||
/*!
|
||||
* \brief Set an icon to display
|
||||
* \param iconName Name of the icon
|
||||
*/
|
||||
void setIcon(const QString& iconName);
|
||||
|
||||
/*!
|
||||
* \brief Set action buttons for the notification. Whenever an action is
|
||||
* activated, the actionActivated() signal is emitted with the list
|
||||
* index of the activated action.
|
||||
* \param actions List of action button titles
|
||||
* \param defaultAction Index of the default action which gets activated
|
||||
* when the notification body is clicked
|
||||
* \sa actionActivated()
|
||||
*/
|
||||
void setActions(const QStringList& actions, int defaultAction = -1);
|
||||
|
||||
/*!
|
||||
* \brief Set the timeout for the notification
|
||||
* \param timeout Milliseconds for timeout, or zero to never time out.
|
||||
*/
|
||||
void setTimeout(int timeout);
|
||||
|
||||
/*!
|
||||
* \brief Set notification hint.
|
||||
* \note For description of Hints, see http://developer.gnome.org/notification-spec/#hints
|
||||
* \note For D-Bus-to-Qt mappings, see https://qt-project.org/doc/qdbustypesystem.html
|
||||
* \param hint Hint name
|
||||
* \param value The hint data
|
||||
*/
|
||||
void setHint(const QString& hint, const QVariant& value);
|
||||
|
||||
/*!
|
||||
* \brief Set the "urgency" hint
|
||||
* \param urgency
|
||||
*/
|
||||
void setUrgencyHint(Urgency urgency);
|
||||
|
||||
/*!
|
||||
* \brief Remove all hints that were set
|
||||
* \sa setHint()
|
||||
*/
|
||||
void clearHints();
|
||||
|
||||
/*!
|
||||
* \brief returns a list of optional capabilities supported by the server.
|
||||
* For the list, see http://developer.gnome.org/notification-spec/#commands
|
||||
*/
|
||||
QStringList getCapabilities();
|
||||
|
||||
/*!
|
||||
* \brief Returns information about the notifications server
|
||||
*/
|
||||
const ServerInfo serverInfo();
|
||||
|
||||
/*!
|
||||
* \brief Convenience function to create and display a notification for the most common
|
||||
* cases. For anything more complex, create a Notification object, set the
|
||||
* desired properties and call update(). (That's what this does internally.)
|
||||
* \sa Notification()
|
||||
*/
|
||||
static void notify(const QString& summary,
|
||||
const QString& body = QString(),
|
||||
const QString& iconName = QString()
|
||||
);
|
||||
|
||||
public slots:
|
||||
/*!
|
||||
* \brief Display the notification or update it if it's already visible
|
||||
*/
|
||||
void update();
|
||||
|
||||
/*!
|
||||
* \brief Causes a notification to be forcefully closed and removed from the user's view.
|
||||
* It can be used, for example, in the event that what the notification pertains to
|
||||
* is no longer relevant, or to cancel a notification with no expiration time.
|
||||
*/
|
||||
void close();
|
||||
|
||||
signals:
|
||||
/*!
|
||||
* \brief Emitted when the notification is closed
|
||||
* \param reason How notification was closed
|
||||
*/
|
||||
void notificationClosed(LXQt::Notification::CloseReason reason);
|
||||
|
||||
/*!
|
||||
* \brief Emitted when an action button is activated.
|
||||
* \param actionNumber Index of the actions array for the activated button.
|
||||
* \sa setActions()
|
||||
*/
|
||||
void actionActivated(int actionNumber);
|
||||
|
||||
private:
|
||||
Q_DECLARE_PRIVATE(Notification)
|
||||
NotificationPrivate* const d_ptr;
|
||||
};
|
||||
|
||||
} // namespace LXQt
|
||||
#endif // LXQTNOTIFICATION_H
|
@ -1,67 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright (C) 2012 Alec Moskvin <alecm@gmx.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
#ifndef LXQTNOTIFICATION_P_H
|
||||
#define LXQTNOTIFICATION_P_H
|
||||
|
||||
#include "lxqtnotification.h"
|
||||
#include "notifications_interface.h"
|
||||
|
||||
namespace LXQt
|
||||
{
|
||||
|
||||
class NotificationPrivate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
NotificationPrivate(const QString& summary, Notification* parent);
|
||||
~NotificationPrivate();
|
||||
|
||||
void update();
|
||||
void close();
|
||||
void setActions(QStringList actions, int defaultAction);
|
||||
const Notification::ServerInfo serverInfo();
|
||||
|
||||
public slots:
|
||||
void handleAction(uint id, QString key);
|
||||
void notificationClosed(uint, uint);
|
||||
|
||||
private:
|
||||
OrgFreedesktopNotificationsInterface* mInterface;
|
||||
uint mId;
|
||||
|
||||
QString mSummary;
|
||||
QString mBody;
|
||||
QString mIconName;
|
||||
QStringList mActions;
|
||||
QVariantMap mHints;
|
||||
int mDefaultAction;
|
||||
int mTimeout;
|
||||
|
||||
Notification* const q_ptr;
|
||||
Q_DECLARE_PUBLIC(Notification)
|
||||
};
|
||||
|
||||
} // namespace LXQt
|
||||
#endif // LXQTNOTIFICATION_P_H
|
@ -1,179 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright: 2010-2011 Razor team
|
||||
* Authors:
|
||||
* Alexander Sokoloff <sokoloff.a@gmail.com>
|
||||
*
|
||||
* This program or library is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
|
||||
#include "lxqtplugininfo.h"
|
||||
#include <QObject>
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
#include <QTranslator>
|
||||
#include <QCoreApplication>
|
||||
#include <QLibrary>
|
||||
#include <QDebug>
|
||||
|
||||
using namespace LXQt;
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
PluginInfo::PluginInfo():
|
||||
XdgDesktopFile()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
bool PluginInfo::load(const QString& fileName)
|
||||
{
|
||||
XdgDesktopFile::load(fileName);
|
||||
mId = QFileInfo(fileName).completeBaseName();
|
||||
return isValid();
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
bool PluginInfo::isValid() const
|
||||
{
|
||||
return XdgDesktopFile::isValid();
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
QLibrary* PluginInfo::loadLibrary(const QString& libDir) const
|
||||
{
|
||||
const QFileInfo fi = QFileInfo(fileName());
|
||||
const QString path = fi.canonicalPath();
|
||||
const QString baseName = value("X-LXQt-Library", fi.completeBaseName()).toString();
|
||||
|
||||
const QString soPath = QDir(libDir).filePath(QString("lib%2.so").arg(baseName));
|
||||
QLibrary* library = new QLibrary(soPath);
|
||||
|
||||
if (!library->load())
|
||||
{
|
||||
qWarning() << QString("Can't load plugin lib \"%1\"").arg(soPath) << library->errorString();
|
||||
delete library;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const QString locale = QLocale::system().name();
|
||||
QTranslator* translator = new QTranslator(library);
|
||||
|
||||
translator->load(QString("%1/%2/%2_%3.qm").arg(path, baseName, locale));
|
||||
qApp->installTranslator(translator);
|
||||
|
||||
return library;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
PluginInfoList PluginInfo::search(const QStringList& desktopFilesDirs, const QString& serviceType, const QString& nameFilter)
|
||||
{
|
||||
QList<PluginInfo> res;
|
||||
QSet<QString> processed;
|
||||
|
||||
foreach (const QString &desktopFilesDir, desktopFilesDirs)
|
||||
{
|
||||
const QDir dir(desktopFilesDir);
|
||||
const QFileInfoList files = dir.entryInfoList(QStringList(nameFilter), QDir::Files | QDir::Readable);
|
||||
foreach (const QFileInfo &file, files)
|
||||
{
|
||||
if (processed.contains(file.fileName()))
|
||||
continue;
|
||||
|
||||
processed << file.fileName();
|
||||
|
||||
PluginInfo item;
|
||||
item.load(file.canonicalFilePath());
|
||||
|
||||
if (item.isValid() && item.serviceType() == serviceType)
|
||||
res.append(item);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
PluginInfoList PluginInfo::search(const QString& desktopFilesDir, const QString& serviceType, const QString& nameFilter)
|
||||
{
|
||||
return search(QStringList(desktopFilesDir), serviceType, nameFilter);
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
QDebug operator<<(QDebug dbg, const LXQt::PluginInfo &pluginInfo)
|
||||
{
|
||||
dbg.nospace() << QString("%1").arg(pluginInfo.id());
|
||||
return dbg.space();
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
QDebug operator<<(QDebug dbg, const LXQt::PluginInfo * const pluginInfo)
|
||||
{
|
||||
return operator<<(dbg, *pluginInfo);
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
QDebug operator<<(QDebug dbg, const PluginInfoList& list)
|
||||
{
|
||||
dbg.nospace() << '(';
|
||||
for (int i=0; i<list.size(); ++i)
|
||||
{
|
||||
if (i) dbg.nospace() << ", ";
|
||||
dbg << list.at(i);
|
||||
}
|
||||
dbg << ')';
|
||||
return dbg.space();
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
QDebug operator<<(QDebug dbg, const PluginInfoList* const pluginInfoList)
|
||||
{
|
||||
return operator<<(dbg, *pluginInfoList);
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright: 2010-2011 Razor team
|
||||
* Authors:
|
||||
* Alexander Sokoloff <sokoloff.a@gmail.com>
|
||||
*
|
||||
* This program or library is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
|
||||
#ifndef LXQTPLUGININFO_H
|
||||
#define LXQTPLUGININFO_H
|
||||
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QtAlgorithms>
|
||||
#include <QDebug>
|
||||
#include "lxqtglobals.h"
|
||||
|
||||
#include <XdgDesktopFile>
|
||||
|
||||
class QLibrary;
|
||||
|
||||
namespace LXQt
|
||||
{
|
||||
|
||||
/*!
|
||||
Every plugin needs a .desktop file that describes it. The basename of this file must
|
||||
be same as the basename of the plugin library.
|
||||
|
||||
lxqtpanel_clock2.desktop file
|
||||
|
||||
[Desktop Entry]
|
||||
Type=Service
|
||||
ServiceTypes=LXQtPanel/Plugin
|
||||
Name=Clock
|
||||
Comment=Clock and calendar
|
||||
|
||||
PluginInfo class gives the interface for reading the values from the plugin .desktop file.
|
||||
This is a pure virtual class, you must implement libraryDir(), translationDir(), and instance() methods.
|
||||
*/
|
||||
class LXQT_API PluginInfo: public XdgDesktopFile
|
||||
{
|
||||
public:
|
||||
/// Constructs a PluginInfo object for accessing the info stored in the .desktop file.
|
||||
explicit PluginInfo();
|
||||
|
||||
//! Reimplemented from XdgDesktopFile.
|
||||
virtual bool load(const QString& fileName);
|
||||
|
||||
|
||||
//! Reimplemented from XdgDesktopFile.
|
||||
//PluginInfo& operator=(const PluginInfo& other);
|
||||
|
||||
|
||||
//! Returns identification string of this plugin, identified plugin type. Now id is part of the filename.
|
||||
QString id() const { return mId; }
|
||||
|
||||
//! This function is provided for convenience. It's equivalent to calling value("ServiceTypes").toString().
|
||||
QString serviceType() const { return value("ServiceTypes").toString(); }
|
||||
|
||||
//! Reimplemented from XdgDesktopFile.
|
||||
virtual bool isValid() const;
|
||||
|
||||
/*! Loads the library and returns QLibrary object if the library was loaded successfully; otherwise returns 0.
|
||||
@parm libDir directory where placed the plugin .so file. */
|
||||
QLibrary* loadLibrary(const QString& libDir) const;
|
||||
|
||||
|
||||
/*! Returns a list of PluginInfo objects for the matched files in the directories.
|
||||
@param desktopFilesDirs - scanned directories names.
|
||||
@param serviceType - type of the plugin, for example "LXQtPanel/Plugin".
|
||||
@param nameFilter - wildcard filter that understands * and ? wildcards.
|
||||
|
||||
If the same filename is located under multiple directories only the first file should be used.
|
||||
*/
|
||||
static QList<PluginInfo> search(const QStringList& desktopFilesDirs, const QString& serviceType, const QString& nameFilter="*");
|
||||
|
||||
/// This function is provided for convenience. It's equivalent to new calling search(QString(desktopFilesDir), serviceType, nameFilter)
|
||||
static QList<PluginInfo> search(const QString& desktopFilesDir, const QString& serviceType, const QString& nameFilter="*");
|
||||
|
||||
private:
|
||||
QString mId;
|
||||
};
|
||||
|
||||
typedef QList<PluginInfo> PluginInfoList;
|
||||
|
||||
} // namespace LXQt
|
||||
|
||||
QDebug operator<<(QDebug dbg, const LXQt::PluginInfo& pi);
|
||||
QDebug operator<<(QDebug dbg, const LXQt::PluginInfo* const pi);
|
||||
|
||||
QDebug operator<<(QDebug dbg, const LXQt::PluginInfoList& list);
|
||||
QDebug operator<<(QDebug dbg, const LXQt::PluginInfoList* const pluginInfoList);
|
||||
|
||||
#endif // LXQTPLUGININFO_H
|
@ -1,96 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright: 2010-2011 Razor team
|
||||
* Authors:
|
||||
* Alexander Sokoloff <sokoloff.a@gmail.com>
|
||||
*
|
||||
* This program or library is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
|
||||
#include "lxqtpower.h"
|
||||
#include "lxqtpowerproviders.h"
|
||||
#include <QtAlgorithms>
|
||||
#include <QDebug>
|
||||
|
||||
using namespace LXQt;
|
||||
|
||||
Power::Power(bool useLxqtSessionProvider, QObject * parent /*= nullptr*/) :
|
||||
QObject(parent)
|
||||
{
|
||||
mProviders.append(new CustomProvider(this));
|
||||
if (useLxqtSessionProvider)
|
||||
mProviders.append(new LXQtProvider(this));
|
||||
mProviders.append(new SystemdProvider(this));
|
||||
mProviders.append(new UPowerProvider(this));
|
||||
mProviders.append(new ConsoleKitProvider(this));
|
||||
mProviders.append(new LxSessionProvider(this));
|
||||
}
|
||||
|
||||
Power::Power(QObject * parent /*= nullptr*/)
|
||||
: Power(true, parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Power::~Power()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool Power::canAction(Power::Action action) const
|
||||
{
|
||||
foreach(PowerProvider* provider, mProviders)
|
||||
{
|
||||
if (provider->canAction(action))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Power::doAction(Power::Action action)
|
||||
{
|
||||
foreach(PowerProvider* provider, mProviders)
|
||||
{
|
||||
if (provider->canAction(action) &&
|
||||
provider->doAction(action)
|
||||
)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Power::canLogout() const { return canAction(PowerLogout); }
|
||||
bool Power::canHibernate() const { return canAction(PowerHibernate); }
|
||||
bool Power::canReboot() const { return canAction(PowerReboot); }
|
||||
bool Power::canShutdown() const { return canAction(PowerShutdown); }
|
||||
bool Power::canSuspend() const { return canAction(PowerSuspend); }
|
||||
|
||||
bool Power::logout() { return doAction(PowerLogout); }
|
||||
bool Power::hibernate() { return doAction(PowerHibernate); }
|
||||
bool Power::reboot() { return doAction(PowerReboot); }
|
||||
bool Power::shutdown() { return doAction(PowerShutdown); }
|
||||
bool Power::suspend() { return doAction(PowerSuspend); }
|
@ -1,115 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright: 2010-2011 Razor team
|
||||
* Authors:
|
||||
* Alexander Sokoloff <sokoloff.a@gmail.com>
|
||||
*
|
||||
* This program or library is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
|
||||
#ifndef LXQTPOWER_H
|
||||
#define LXQTPOWER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QList>
|
||||
#include "lxqtglobals.h"
|
||||
|
||||
namespace LXQt
|
||||
{
|
||||
|
||||
|
||||
class PowerProvider;
|
||||
|
||||
/*! Power class provides an interface to control system-wide power and session management.
|
||||
It allows logout from the user session, hibernate, reboot, shutdown and suspend computer.
|
||||
This is a wrapper class. All the real work is done in the PowerWorker classes.
|
||||
*/
|
||||
class LXQT_API Power : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/// Power can perform next actions:
|
||||
enum Action{
|
||||
PowerLogout, /// Close the current user session.
|
||||
PowerHibernate, /// Hibernate the comupter
|
||||
PowerReboot, /// Reboot the computer
|
||||
PowerShutdown, /// Shutdown the computer
|
||||
PowerSuspend /// Suspend the computer
|
||||
};
|
||||
|
||||
/*!
|
||||
* Constructs the Power object.
|
||||
* \param useLxqtSessionProvider indicates if the DBus methods
|
||||
* provided by lxqt-session should be considered. This is useful to
|
||||
* avoid recursion if the lxqt-session wants to provide some of the
|
||||
* methods by itself with internal use of this object.
|
||||
*/
|
||||
explicit Power(bool useLxqtSessionProvider, QObject *parent = nullptr);
|
||||
/// Constructs a Power with using the lxqt-session provider.
|
||||
explicit Power(QObject *parent = nullptr);
|
||||
|
||||
/// Destroys the object.
|
||||
virtual ~Power();
|
||||
|
||||
/// Returns true if the Power can perform action.
|
||||
bool canAction(Action action) const;
|
||||
|
||||
//! This function is provided for convenience. It's equivalent to calling canAction(PowerLogout).
|
||||
bool canLogout() const;
|
||||
|
||||
//! This function is provided for convenience. It's equivalent to calling canAction(PowerHibernate).
|
||||
bool canHibernate() const;
|
||||
|
||||
//! This function is provided for convenience. It's equivalent to calling canAction(PowerReboot).
|
||||
bool canReboot() const;
|
||||
|
||||
//! This function is provided for convenience. It's equivalent to calling canAction(PowerShutdown).
|
||||
bool canShutdown() const;
|
||||
|
||||
//! This function is provided for convenience. It's equivalent to calling canAction(PowerSuspend).
|
||||
bool canSuspend() const;
|
||||
|
||||
public slots:
|
||||
/// Performs the requested action.
|
||||
bool doAction(Action action);
|
||||
|
||||
//! This function is provided for convenience. It's equivalent to calling doAction(PowerLogout).
|
||||
bool logout();
|
||||
|
||||
//! This function is provided for convenience. It's equivalent to calling doAction(PowerHibernate).
|
||||
bool hibernate();
|
||||
|
||||
//! This function is provided for convenience. It's equivalent to calling doAction(PowerReboot).
|
||||
bool reboot();
|
||||
|
||||
//! This function is provided for convenience. It's equivalent to calling doAction(PowerShutdown).
|
||||
bool shutdown();
|
||||
|
||||
//! This function is provided for convenience. It's equivalent to calling doAction(PowerSuspend).
|
||||
bool suspend();
|
||||
|
||||
private:
|
||||
QList<PowerProvider*> mProviders;
|
||||
};
|
||||
|
||||
} // namespace LXQt
|
||||
#endif // LXQTPOWER_H
|
@ -1,691 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright: 2010-2011 Razor team
|
||||
* Authors:
|
||||
* Alexander Sokoloff <sokoloff.a@gmail.com>
|
||||
* Petr Vanek <petr@scribus.info>
|
||||
*
|
||||
* This program or library is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
|
||||
#include "lxqtpowerproviders.h"
|
||||
#include <QDBusInterface>
|
||||
#include <QProcess>
|
||||
#include <QDebug>
|
||||
#include "lxqtnotification.h"
|
||||
#include <signal.h> // for kill()
|
||||
|
||||
#define UPOWER_SERVICE "org.freedesktop.UPower"
|
||||
#define UPOWER_PATH "/org/freedesktop/UPower"
|
||||
#define UPOWER_INTERFACE UPOWER_SERVICE
|
||||
|
||||
#define CONSOLEKIT_SERVICE "org.freedesktop.ConsoleKit"
|
||||
#define CONSOLEKIT_PATH "/org/freedesktop/ConsoleKit/Manager"
|
||||
#define CONSOLEKIT_INTERFACE "org.freedesktop.ConsoleKit.Manager"
|
||||
|
||||
#define SYSTEMD_SERVICE "org.freedesktop.login1"
|
||||
#define SYSTEMD_PATH "/org/freedesktop/login1"
|
||||
#define SYSTEMD_INTERFACE "org.freedesktop.login1.Manager"
|
||||
|
||||
#define LXQT_SERVICE "org.lxqt.session"
|
||||
#define LXQT_PATH "/LXQtSession"
|
||||
#define LXQT_INTERFACE "org.lxqt.session"
|
||||
|
||||
#define PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties"
|
||||
|
||||
using namespace LXQt;
|
||||
|
||||
/************************************************
|
||||
Helper func
|
||||
************************************************/
|
||||
void printDBusMsg(const QDBusMessage &msg)
|
||||
{
|
||||
qWarning() << "** Dbus error **************************";
|
||||
qWarning() << "Error name " << msg.errorName();
|
||||
qWarning() << "Error msg " << msg.errorMessage();
|
||||
qWarning() << "****************************************";
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
Helper func
|
||||
************************************************/
|
||||
static bool dbusCall(const QString &service,
|
||||
const QString &path,
|
||||
const QString &interface,
|
||||
const QDBusConnection &connection,
|
||||
const QString & method,
|
||||
PowerProvider::DbusErrorCheck errorCheck = PowerProvider::CheckDBUS
|
||||
)
|
||||
{
|
||||
QDBusInterface dbus(service, path, interface, connection);
|
||||
if (!dbus.isValid())
|
||||
{
|
||||
qWarning() << "dbusCall: QDBusInterface is invalid" << service << path << interface << method;
|
||||
if (errorCheck == PowerProvider::CheckDBUS)
|
||||
{
|
||||
Notification::notify(
|
||||
QObject::tr("Power Manager Error"),
|
||||
QObject::tr("QDBusInterface is invalid")+ "\n\n" + service + " " + path + " " + interface + " " + method,
|
||||
"lxqt-logo.png");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QDBusMessage msg = dbus.call(method);
|
||||
|
||||
if (!msg.errorName().isEmpty())
|
||||
{
|
||||
printDBusMsg(msg);
|
||||
if (errorCheck == PowerProvider::CheckDBUS)
|
||||
{
|
||||
Notification::notify(
|
||||
QObject::tr("Power Manager Error (D-BUS call)"),
|
||||
msg.errorName() + "\n\n" + msg.errorMessage(),
|
||||
"lxqt-logo.png");
|
||||
}
|
||||
}
|
||||
|
||||
// If the method no returns value, we believe that it was successful.
|
||||
return msg.arguments().isEmpty() ||
|
||||
msg.arguments().constFirst().isNull() ||
|
||||
msg.arguments().constFirst().toBool();
|
||||
}
|
||||
|
||||
/************************************************
|
||||
Helper func
|
||||
|
||||
Just like dbusCall(), except that systemd
|
||||
returns a string instead of a bool, and it takes
|
||||
an "interactivity boolean" as an argument.
|
||||
************************************************/
|
||||
static bool dbusCallSystemd(const QString &service,
|
||||
const QString &path,
|
||||
const QString &interface,
|
||||
const QDBusConnection &connection,
|
||||
const QString &method,
|
||||
bool needBoolArg,
|
||||
PowerProvider::DbusErrorCheck errorCheck = PowerProvider::CheckDBUS
|
||||
)
|
||||
{
|
||||
QDBusInterface dbus(service, path, interface, connection);
|
||||
if (!dbus.isValid())
|
||||
{
|
||||
qWarning() << "dbusCall: QDBusInterface is invalid" << service << path << interface << method;
|
||||
if (errorCheck == PowerProvider::CheckDBUS)
|
||||
{
|
||||
Notification::notify(
|
||||
QObject::tr("Power Manager Error"),
|
||||
QObject::tr("QDBusInterface is invalid")+ "\n\n" + service + " " + path + " " + interface + " " + method,
|
||||
"lxqt-logo.png");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QDBusMessage msg = dbus.call(method, needBoolArg ? QVariant(true) : QVariant());
|
||||
|
||||
if (!msg.errorName().isEmpty())
|
||||
{
|
||||
printDBusMsg(msg);
|
||||
if (errorCheck == PowerProvider::CheckDBUS)
|
||||
{
|
||||
Notification::notify(
|
||||
QObject::tr("Power Manager Error (D-BUS call)"),
|
||||
msg.errorName() + "\n\n" + msg.errorMessage(),
|
||||
"lxqt-logo.png");
|
||||
}
|
||||
}
|
||||
|
||||
// If the method no returns value, we believe that it was successful.
|
||||
if (msg.arguments().isEmpty() || msg.arguments().constFirst().isNull())
|
||||
return true;
|
||||
|
||||
QString response = msg.arguments().constFirst().toString();
|
||||
qDebug() << "systemd:" << method << "=" << response;
|
||||
return response == "yes" || response == "challenge";
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
Helper func
|
||||
************************************************/
|
||||
bool dbusGetProperty(const QString &service,
|
||||
const QString &path,
|
||||
const QString &interface,
|
||||
const QDBusConnection &connection,
|
||||
const QString & property
|
||||
)
|
||||
{
|
||||
QDBusInterface dbus(service, path, interface, connection);
|
||||
if (!dbus.isValid())
|
||||
{
|
||||
qWarning() << "dbusGetProperty: QDBusInterface is invalid" << service << path << interface << property;
|
||||
// Notification::notify(QObject::tr("LXQt Power Manager"),
|
||||
// "lxqt-logo.png",
|
||||
// QObject::tr("Power Manager Error"),
|
||||
// QObject::tr("QDBusInterface is invalid")+ "\n\n" + service +" " + path +" " + interface +" " + property);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QDBusMessage msg = dbus.call("Get", dbus.interface(), property);
|
||||
|
||||
if (!msg.errorName().isEmpty())
|
||||
{
|
||||
printDBusMsg(msg);
|
||||
// Notification::notify(QObject::tr("LXQt Power Manager"),
|
||||
// "lxqt-logo.png",
|
||||
// QObject::tr("Power Manager Error (Get Property)"),
|
||||
// msg.errorName() + "\n\n" + msg.errorMessage());
|
||||
}
|
||||
|
||||
return !msg.arguments().isEmpty() &&
|
||||
msg.arguments().constFirst().value<QDBusVariant>().variant().toBool();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/************************************************
|
||||
PowerProvider
|
||||
************************************************/
|
||||
PowerProvider::PowerProvider(QObject *parent):
|
||||
QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PowerProvider::~PowerProvider()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
/************************************************
|
||||
UPowerProvider
|
||||
************************************************/
|
||||
UPowerProvider::UPowerProvider(QObject *parent):
|
||||
PowerProvider(parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
UPowerProvider::~UPowerProvider()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool UPowerProvider::canAction(Power::Action action) const
|
||||
{
|
||||
QString command;
|
||||
QString property;
|
||||
switch (action)
|
||||
{
|
||||
case Power::PowerHibernate:
|
||||
property = "CanHibernate";
|
||||
command = "HibernateAllowed";
|
||||
break;
|
||||
|
||||
case Power::PowerSuspend:
|
||||
property = "CanSuspend";
|
||||
command = "SuspendAllowed";
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return dbusGetProperty( // Whether the system is able to hibernate.
|
||||
UPOWER_SERVICE,
|
||||
UPOWER_PATH,
|
||||
PROPERTIES_INTERFACE,
|
||||
QDBusConnection::systemBus(),
|
||||
property
|
||||
)
|
||||
&&
|
||||
dbusCall( // Check if the caller has (or can get) the PolicyKit privilege to call command.
|
||||
UPOWER_SERVICE,
|
||||
UPOWER_PATH,
|
||||
UPOWER_INTERFACE,
|
||||
QDBusConnection::systemBus(),
|
||||
command,
|
||||
// canAction should be always silent because it can freeze
|
||||
// g_main_context_iteration Qt event loop in QMessageBox
|
||||
// on panel startup if there is no DBUS running.
|
||||
PowerProvider::DontCheckDBUS
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
bool UPowerProvider::doAction(Power::Action action)
|
||||
{
|
||||
QString command;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case Power::PowerHibernate:
|
||||
command = "Hibernate";
|
||||
break;
|
||||
|
||||
case Power::PowerSuspend:
|
||||
command = "Suspend";
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return dbusCall(UPOWER_SERVICE,
|
||||
UPOWER_PATH,
|
||||
UPOWER_INTERFACE,
|
||||
QDBusConnection::systemBus(),
|
||||
command );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/************************************************
|
||||
ConsoleKitProvider
|
||||
************************************************/
|
||||
ConsoleKitProvider::ConsoleKitProvider(QObject *parent):
|
||||
PowerProvider(parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ConsoleKitProvider::~ConsoleKitProvider()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool ConsoleKitProvider::canAction(Power::Action action) const
|
||||
{
|
||||
QString command;
|
||||
switch (action)
|
||||
{
|
||||
case Power::PowerReboot:
|
||||
command = "CanReboot";
|
||||
break;
|
||||
|
||||
case Power::PowerShutdown:
|
||||
command = "CanPowerOff";
|
||||
break;
|
||||
|
||||
case Power::PowerHibernate:
|
||||
command = "CanHibernate";
|
||||
break;
|
||||
|
||||
case Power::PowerSuspend:
|
||||
command = "CanSuspend";
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return dbusCallSystemd(CONSOLEKIT_SERVICE,
|
||||
CONSOLEKIT_PATH,
|
||||
CONSOLEKIT_INTERFACE,
|
||||
QDBusConnection::systemBus(),
|
||||
command,
|
||||
false,
|
||||
// canAction should be always silent because it can freeze
|
||||
// g_main_context_iteration Qt event loop in QMessageBox
|
||||
// on panel startup if there is no DBUS running.
|
||||
PowerProvider::DontCheckDBUS
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
bool ConsoleKitProvider::doAction(Power::Action action)
|
||||
{
|
||||
QString command;
|
||||
switch (action)
|
||||
{
|
||||
case Power::PowerReboot:
|
||||
command = "Reboot";
|
||||
break;
|
||||
|
||||
case Power::PowerShutdown:
|
||||
command = "PowerOff";
|
||||
break;
|
||||
|
||||
case Power::PowerHibernate:
|
||||
command = "Hibernate";
|
||||
break;
|
||||
|
||||
case Power::PowerSuspend:
|
||||
command = "Suspend";
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return dbusCallSystemd(CONSOLEKIT_SERVICE,
|
||||
CONSOLEKIT_PATH,
|
||||
CONSOLEKIT_INTERFACE,
|
||||
QDBusConnection::systemBus(),
|
||||
command,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/************************************************
|
||||
SystemdProvider
|
||||
|
||||
http://www.freedesktop.org/wiki/Software/systemd/logind
|
||||
************************************************/
|
||||
|
||||
SystemdProvider::SystemdProvider(QObject *parent):
|
||||
PowerProvider(parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SystemdProvider::~SystemdProvider()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool SystemdProvider::canAction(Power::Action action) const
|
||||
{
|
||||
QString command;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case Power::PowerReboot:
|
||||
command = "CanReboot";
|
||||
break;
|
||||
|
||||
case Power::PowerShutdown:
|
||||
command = "CanPowerOff";
|
||||
break;
|
||||
|
||||
case Power::PowerSuspend:
|
||||
command = "CanSuspend";
|
||||
break;
|
||||
|
||||
case Power::PowerHibernate:
|
||||
command = "CanHibernate";
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return dbusCallSystemd(SYSTEMD_SERVICE,
|
||||
SYSTEMD_PATH,
|
||||
SYSTEMD_INTERFACE,
|
||||
QDBusConnection::systemBus(),
|
||||
command,
|
||||
false,
|
||||
// canAction should be always silent because it can freeze
|
||||
// g_main_context_iteration Qt event loop in QMessageBox
|
||||
// on panel startup if there is no DBUS running.
|
||||
PowerProvider::DontCheckDBUS
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
bool SystemdProvider::doAction(Power::Action action)
|
||||
{
|
||||
QString command;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case Power::PowerReboot:
|
||||
command = "Reboot";
|
||||
break;
|
||||
|
||||
case Power::PowerShutdown:
|
||||
command = "PowerOff";
|
||||
break;
|
||||
|
||||
case Power::PowerSuspend:
|
||||
command = "Suspend";
|
||||
break;
|
||||
|
||||
case Power::PowerHibernate:
|
||||
command = "Hibernate";
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return dbusCallSystemd(SYSTEMD_SERVICE,
|
||||
SYSTEMD_PATH,
|
||||
SYSTEMD_INTERFACE,
|
||||
QDBusConnection::systemBus(),
|
||||
command,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
LXQtProvider
|
||||
************************************************/
|
||||
LXQtProvider::LXQtProvider(QObject *parent):
|
||||
PowerProvider(parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
LXQtProvider::~LXQtProvider()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool LXQtProvider::canAction(Power::Action action) const
|
||||
{
|
||||
QString command;
|
||||
switch (action)
|
||||
{
|
||||
case Power::PowerLogout:
|
||||
command = "canLogout";
|
||||
break;
|
||||
case Power::PowerReboot:
|
||||
command = "canReboot";
|
||||
break;
|
||||
case Power::PowerShutdown:
|
||||
command = "canPowerOff";
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
// there can be case when lxqtsession-session does not run
|
||||
return dbusCall(LXQT_SERVICE, LXQT_PATH, LXQT_SERVICE,
|
||||
QDBusConnection::sessionBus(), command,
|
||||
PowerProvider::DontCheckDBUS);
|
||||
}
|
||||
|
||||
|
||||
bool LXQtProvider::doAction(Power::Action action)
|
||||
{
|
||||
QString command;
|
||||
switch (action)
|
||||
{
|
||||
case Power::PowerLogout:
|
||||
command = "logout";
|
||||
break;
|
||||
case Power::PowerReboot:
|
||||
command = "reboot";
|
||||
break;
|
||||
case Power::PowerShutdown:
|
||||
command = "powerOff";
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return dbusCall(LXQT_SERVICE,
|
||||
LXQT_PATH,
|
||||
LXQT_INTERFACE,
|
||||
QDBusConnection::sessionBus(),
|
||||
command
|
||||
);
|
||||
}
|
||||
|
||||
/************************************************
|
||||
LxSessionProvider
|
||||
************************************************/
|
||||
LxSessionProvider::LxSessionProvider(QObject *parent):
|
||||
PowerProvider(parent)
|
||||
{
|
||||
pid = (Q_PID)qgetenv("_LXSESSION_PID").toLong();
|
||||
}
|
||||
|
||||
|
||||
LxSessionProvider::~LxSessionProvider()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool LxSessionProvider::canAction(Power::Action action) const
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case Power::PowerLogout:
|
||||
return pid != 0;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool LxSessionProvider::doAction(Power::Action action)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case Power::PowerLogout:
|
||||
if(pid)
|
||||
::kill(pid, SIGTERM);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
HalProvider
|
||||
************************************************/
|
||||
HalProvider::HalProvider(QObject *parent):
|
||||
PowerProvider(parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HalProvider::~HalProvider()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool HalProvider::canAction(Power::Action action) const
|
||||
{
|
||||
Q_UNUSED(action)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool HalProvider::doAction(Power::Action action)
|
||||
{
|
||||
Q_UNUSED(action)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
CustomProvider
|
||||
************************************************/
|
||||
CustomProvider::CustomProvider(QObject *parent):
|
||||
PowerProvider(parent),
|
||||
mSettings("power")
|
||||
{
|
||||
}
|
||||
|
||||
CustomProvider::~CustomProvider()
|
||||
{
|
||||
}
|
||||
|
||||
bool CustomProvider::canAction(Power::Action action) const
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case Power::PowerShutdown:
|
||||
return mSettings.contains("shutdownCommand");
|
||||
|
||||
case Power::PowerReboot:
|
||||
return mSettings.contains("rebootCommand");
|
||||
|
||||
case Power::PowerHibernate:
|
||||
return mSettings.contains("hibernateCommand");
|
||||
|
||||
case Power::PowerSuspend:
|
||||
return mSettings.contains("suspendCommand");
|
||||
|
||||
case Power::PowerLogout:
|
||||
return mSettings.contains("logoutCommand");
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool CustomProvider::doAction(Power::Action action)
|
||||
{
|
||||
QString command;
|
||||
|
||||
switch(action)
|
||||
{
|
||||
case Power::PowerShutdown:
|
||||
command = mSettings.value("shutdownCommand").toString();
|
||||
break;
|
||||
|
||||
case Power::PowerReboot:
|
||||
command = mSettings.value("rebootCommand").toString();
|
||||
break;
|
||||
|
||||
case Power::PowerHibernate:
|
||||
command = mSettings.value("hibernateCommand").toString();
|
||||
break;
|
||||
|
||||
case Power::PowerSuspend:
|
||||
command = mSettings.value("suspendCommand").toString();
|
||||
break;
|
||||
|
||||
case Power::PowerLogout:
|
||||
command = mSettings.value("logoutCommand").toString();
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return QProcess::startDetached(command);
|
||||
}
|
@ -1,159 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright: 2010-2011 Razor team
|
||||
* Authors:
|
||||
* Alexander Sokoloff <sokoloff.a@gmail.com>
|
||||
*
|
||||
* This program or library is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
|
||||
#ifndef LXQTPOWER_PROVIDERS_H
|
||||
#define LXQTPOWER_PROVIDERS_H
|
||||
|
||||
#include <QObject>
|
||||
#include <lxqtsettings.h>
|
||||
#include "lxqtpower.h"
|
||||
#include <QProcess> // for PID_T
|
||||
|
||||
namespace LXQt
|
||||
{
|
||||
|
||||
|
||||
class PowerProvider: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
enum DbusErrorCheck {
|
||||
CheckDBUS,
|
||||
DontCheckDBUS
|
||||
};
|
||||
|
||||
explicit PowerProvider(QObject *parent = 0);
|
||||
virtual ~PowerProvider();
|
||||
|
||||
/*! Returns true if the Power can perform action.
|
||||
This is a pure virtual function, and must be reimplemented in subclasses. */
|
||||
virtual bool canAction(Power::Action action) const = 0 ;
|
||||
|
||||
public slots:
|
||||
/*! Performs the requested action.
|
||||
This is a pure virtual function, and must be reimplemented in subclasses. */
|
||||
virtual bool doAction(Power::Action action) = 0;
|
||||
};
|
||||
|
||||
|
||||
class UPowerProvider: public PowerProvider
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
UPowerProvider(QObject *parent = 0);
|
||||
~UPowerProvider();
|
||||
bool canAction(Power::Action action) const;
|
||||
|
||||
public slots:
|
||||
bool doAction(Power::Action action);
|
||||
};
|
||||
|
||||
|
||||
class ConsoleKitProvider: public PowerProvider
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ConsoleKitProvider(QObject *parent = 0);
|
||||
~ConsoleKitProvider();
|
||||
bool canAction(Power::Action action) const;
|
||||
|
||||
public slots:
|
||||
bool doAction(Power::Action action);
|
||||
};
|
||||
|
||||
|
||||
class SystemdProvider: public PowerProvider
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SystemdProvider(QObject *parent = 0);
|
||||
~SystemdProvider();
|
||||
bool canAction(Power::Action action) const;
|
||||
|
||||
public slots:
|
||||
bool doAction(Power::Action action);
|
||||
};
|
||||
|
||||
|
||||
class LXQtProvider: public PowerProvider
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
LXQtProvider(QObject *parent = 0);
|
||||
~LXQtProvider();
|
||||
bool canAction(Power::Action action) const;
|
||||
|
||||
public slots:
|
||||
bool doAction(Power::Action action);
|
||||
};
|
||||
|
||||
class LxSessionProvider: public PowerProvider
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
LxSessionProvider(QObject *parent = 0);
|
||||
~LxSessionProvider();
|
||||
bool canAction(Power::Action action) const;
|
||||
|
||||
public slots:
|
||||
bool doAction(Power::Action action);
|
||||
private:
|
||||
Q_PID pid;
|
||||
};
|
||||
|
||||
class HalProvider: public PowerProvider
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HalProvider(QObject *parent = 0);
|
||||
~HalProvider();
|
||||
bool canAction(Power::Action action) const;
|
||||
|
||||
public slots:
|
||||
bool doAction(Power::Action action);
|
||||
};
|
||||
|
||||
|
||||
class CustomProvider: public PowerProvider
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CustomProvider(QObject *parent = 0);
|
||||
~CustomProvider();
|
||||
bool canAction(Power::Action action) const;
|
||||
|
||||
public slots:
|
||||
bool doAction(Power::Action action);
|
||||
|
||||
private:
|
||||
Settings mSettings;
|
||||
};
|
||||
|
||||
} // namespace LXQt
|
||||
#endif // LXQTPOWER_PROVIDERS_H
|
@ -1,214 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright: 2010-2011 Razor team
|
||||
* Authors:
|
||||
* Petr Vanek <petr@scribus.info>
|
||||
*
|
||||
* This program or library is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
#include "lxqtpowermanager.h"
|
||||
#include "lxqtpower/lxqtpower.h"
|
||||
#include <QDBusInterface>
|
||||
#include <QMessageBox>
|
||||
#include <QApplication>
|
||||
#include <QDesktopWidget>
|
||||
#include <QtDebug>
|
||||
#include "lxqttranslator.h"
|
||||
#include "lxqtglobals.h"
|
||||
#include "lxqtsettings.h"
|
||||
#include <XdgIcon>
|
||||
|
||||
namespace LXQt {
|
||||
|
||||
class LXQT_API MessageBox: public QMessageBox
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(LXQt::MessageBox)
|
||||
|
||||
public:
|
||||
explicit MessageBox(QWidget *parent = 0): QMessageBox(parent) {}
|
||||
|
||||
static QWidget *parentWidget()
|
||||
{
|
||||
const QWidgetList widgets = QApplication::topLevelWidgets();
|
||||
|
||||
if (widgets.count())
|
||||
return widgets.at(0);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool question(const QString& title, const QString& text)
|
||||
{
|
||||
MessageBox msgBox(parentWidget());
|
||||
msgBox.setWindowTitle(title);
|
||||
msgBox.setText(text);
|
||||
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
|
||||
return (msgBox.exec() == QMessageBox::Yes);
|
||||
}
|
||||
|
||||
|
||||
static void warning(const QString& title, const QString& text)
|
||||
{
|
||||
Q_UNUSED(title)
|
||||
Q_UNUSED(text)
|
||||
QMessageBox::warning(parentWidget(), tr("LXQt Power Manager Error"), tr("Hibernate failed."));
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
virtual void resizeEvent(QResizeEvent* event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
const QRect screen = QApplication::desktop()->screenGeometry();
|
||||
move((screen.width() - this->width()) / 2,
|
||||
(screen.height() - this->height()) / 2);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
PowerManager::PowerManager(QObject * parent, bool skipWarning)
|
||||
: QObject(parent),
|
||||
m_skipWarning(skipWarning)
|
||||
{
|
||||
m_power = new Power(this);
|
||||
// connect(m_power, SIGNAL(suspendFail()), this, SLOT(suspendFailed()));
|
||||
// connect(m_power, SIGNAL(hibernateFail()), this, SLOT(hibernateFailed()));
|
||||
// connect(m_power, SIGNAL(monitoring(const QString &)),
|
||||
// this, SLOT(monitoring(const QString&)));
|
||||
|
||||
QString sessionConfig(getenv("LXQT_SESSION_CONFIG"));
|
||||
Settings settings(sessionConfig.isEmpty() ? "session" : sessionConfig);
|
||||
m_skipWarning = settings.value("leave_confirmation").toBool() ? false : true;
|
||||
}
|
||||
|
||||
PowerManager::~PowerManager()
|
||||
{
|
||||
// delete m_power;
|
||||
}
|
||||
|
||||
QList<QAction*> PowerManager::availableActions()
|
||||
{
|
||||
QList<QAction*> ret;
|
||||
QAction * act;
|
||||
|
||||
// TODO/FIXME: icons
|
||||
if (m_power->canHibernate())
|
||||
{
|
||||
act = new QAction(XdgIcon::fromTheme("system-suspend-hibernate"), tr("Hibernate"), this);
|
||||
connect(act, SIGNAL(triggered()), this, SLOT(hibernate()));
|
||||
ret.append(act);
|
||||
}
|
||||
|
||||
if (m_power->canSuspend())
|
||||
{
|
||||
act = new QAction(XdgIcon::fromTheme("system-suspend"), tr("Suspend"), this);
|
||||
connect(act, SIGNAL(triggered()), this, SLOT(suspend()));
|
||||
ret.append(act);
|
||||
}
|
||||
|
||||
if (m_power->canReboot())
|
||||
{
|
||||
act = new QAction(XdgIcon::fromTheme("system-reboot"), tr("Reboot"), this);
|
||||
connect(act, SIGNAL(triggered()), this, SLOT(reboot()));
|
||||
ret.append(act);
|
||||
}
|
||||
|
||||
if (m_power->canShutdown())
|
||||
{
|
||||
act = new QAction(XdgIcon::fromTheme("system-shutdown"), tr("Shutdown"), this);
|
||||
connect(act, SIGNAL(triggered()), this, SLOT(shutdown()));
|
||||
ret.append(act);
|
||||
}
|
||||
|
||||
if (m_power->canLogout())
|
||||
{
|
||||
act = new QAction(XdgIcon::fromTheme("system-log-out"), tr("Logout"), this);
|
||||
connect(act, SIGNAL(triggered()), this, SLOT(logout()));
|
||||
ret.append(act);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void PowerManager::suspend()
|
||||
{
|
||||
if (m_skipWarning ||
|
||||
MessageBox::question(tr("LXQt Session Suspend"),
|
||||
tr("Do you want to really suspend your computer?<p>Suspends the computer into a low power state. System state is not preserved if the power is lost.")))
|
||||
{
|
||||
m_power->suspend();
|
||||
}
|
||||
}
|
||||
|
||||
void PowerManager::hibernate()
|
||||
{
|
||||
if (m_skipWarning ||
|
||||
MessageBox::question(tr("LXQt Session Hibernate"),
|
||||
tr("Do you want to really hibernate your computer?<p>Hibernates the computer into a low power state. System state is preserved if the power is lost.")))
|
||||
{
|
||||
m_power->hibernate();
|
||||
}
|
||||
}
|
||||
|
||||
void PowerManager::reboot()
|
||||
{
|
||||
if (m_skipWarning ||
|
||||
MessageBox::question(tr("LXQt Session Reboot"),
|
||||
tr("Do you want to really restart your computer? All unsaved work will be lost...")))
|
||||
{
|
||||
m_power->reboot();
|
||||
}
|
||||
}
|
||||
|
||||
void PowerManager::shutdown()
|
||||
{
|
||||
if (m_skipWarning ||
|
||||
MessageBox::question(tr("LXQt Session Shutdown"),
|
||||
tr("Do you want to really switch off your computer? All unsaved work will be lost...")))
|
||||
{
|
||||
m_power->shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
void PowerManager::logout()
|
||||
{
|
||||
if (m_skipWarning ||
|
||||
MessageBox::question(tr("LXQt Session Logout"),
|
||||
tr("Do you want to really logout? All unsaved work will be lost...")))
|
||||
{
|
||||
m_power->logout();
|
||||
}
|
||||
}
|
||||
|
||||
void PowerManager::hibernateFailed()
|
||||
{
|
||||
MessageBox::warning(tr("LXQt Power Manager Error"), tr("Hibernate failed."));
|
||||
}
|
||||
|
||||
void PowerManager::suspendFailed()
|
||||
{
|
||||
MessageBox::warning(tr("LXQt Power Manager Error"), tr("Suspend failed."));
|
||||
}
|
||||
|
||||
} // namespace LXQt
|
@ -1,73 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright: 2010-2011 Razor team
|
||||
* Authors:
|
||||
* Petr Vanek <petr@scribus.info>
|
||||
*
|
||||
* This program or library is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
#ifndef LXQTPOWERMANAGER_H
|
||||
#define LXQTPOWERMANAGER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QAction>
|
||||
#include "lxqtglobals.h"
|
||||
|
||||
namespace LXQt
|
||||
{
|
||||
class Power;
|
||||
|
||||
/*! QAction centric menu aware wrapper around lxqtpower
|
||||
*/
|
||||
class LXQT_API PowerManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PowerManager(QObject * parent, bool skipWarning = false);
|
||||
~PowerManager();
|
||||
QList<QAction*> availableActions();
|
||||
|
||||
public slots:
|
||||
// power management
|
||||
void suspend();
|
||||
void hibernate();
|
||||
void reboot();
|
||||
void shutdown();
|
||||
// lxqt session
|
||||
void logout();
|
||||
|
||||
public:
|
||||
bool skipWarning() const { return m_skipWarning; }
|
||||
|
||||
private:
|
||||
LXQt::Power * m_power;
|
||||
bool m_skipWarning;
|
||||
|
||||
private slots:
|
||||
void hibernateFailed();
|
||||
void suspendFailed();
|
||||
};
|
||||
|
||||
} // namespace LXQt
|
||||
|
||||
#endif // LXQTPOWERMANAGER_H
|
@ -1,67 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright (C) 2013 Alec Moskvin <alecm@gmx.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
#include "lxqtprogramfinder.h"
|
||||
#include <wordexp.h>
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
|
||||
using namespace LXQt;
|
||||
|
||||
LXQT_API bool ProgramFinder::programExists(const QString& command)
|
||||
{
|
||||
const QString program = programName(command);
|
||||
if (program[0] == QChar('/'))
|
||||
{
|
||||
QFileInfo fi(program);
|
||||
return fi.isExecutable() && fi.isFile();
|
||||
}
|
||||
|
||||
const QString path = qgetenv("PATH");
|
||||
foreach (const QString& dirName, path.split(":", QString::SkipEmptyParts))
|
||||
{
|
||||
const QFileInfo fi(QDir(dirName), program);
|
||||
if (fi.isExecutable() && fi.isFile())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
LXQT_API QStringList ProgramFinder::findPrograms(const QStringList& commands)
|
||||
{
|
||||
QStringList availPrograms;
|
||||
foreach (const QString& program, commands)
|
||||
if (programExists(program))
|
||||
availPrograms.append(program);
|
||||
return availPrograms;
|
||||
}
|
||||
|
||||
LXQT_API QString ProgramFinder::programName(const QString& command)
|
||||
{
|
||||
wordexp_t we;
|
||||
if (wordexp(command.toLocal8Bit().constData(), &we, WRDE_NOCMD) == 0)
|
||||
if (we.we_wordc > 0)
|
||||
return QString(we.we_wordv[0]);
|
||||
return QString();
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright (C) 2013 Alec Moskvin <alecm@gmx.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
#ifndef LXQTPROGRAMFINDER_H
|
||||
#define LXQTPROGRAMFINDER_H
|
||||
|
||||
#include <QStringList>
|
||||
#include "lxqtglobals.h"
|
||||
|
||||
namespace LXQt
|
||||
{
|
||||
|
||||
namespace ProgramFinder
|
||||
{
|
||||
/*!
|
||||
* \brief programExists Checks if the program needed to execute the given
|
||||
* command is installed
|
||||
* \param command
|
||||
* \return True if the program exists
|
||||
*/
|
||||
LXQT_API bool programExists(const QString& command);
|
||||
|
||||
/*!
|
||||
* \brief findPrograms Filters a list of commands (with arguments) based on
|
||||
* which programs are installed
|
||||
* \param commands Commands to check
|
||||
* \return List of commands which are installed
|
||||
*/
|
||||
LXQT_API QStringList findPrograms(const QStringList& commands);
|
||||
|
||||
/*!
|
||||
* \brief programName Returns the program name given a command
|
||||
* \param command
|
||||
* \return
|
||||
*/
|
||||
LXQT_API QString programName(const QString& command);
|
||||
}
|
||||
|
||||
} // namespace LXQt
|
||||
#endif // LXQTPROGRAMFINDER_H
|
@ -1,326 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright: 2010-2013 Razor team
|
||||
* Authors:
|
||||
* Kuzma Shapran <kuzma.shapran@gmail.com>
|
||||
*
|
||||
* This program or library is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
|
||||
#include "lxqtrotatedwidget.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QImage>
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
#include <QMouseEvent>
|
||||
|
||||
#ifndef QT_NO_WHEELEVENT
|
||||
#include <QWheelEvent>
|
||||
#endif
|
||||
|
||||
#include <QResizeEvent>
|
||||
|
||||
using namespace LXQt;
|
||||
|
||||
RotatedWidget::RotatedWidget(QWidget &content, QWidget *parent, Qt::WindowFlags f)
|
||||
: QWidget(parent, f)
|
||||
, mContent(&content)
|
||||
, mOrigin(Qt::TopLeftCorner)
|
||||
, mTransferMousePressEvent(false)
|
||||
, mTransferMouseReleaseEvent(false)
|
||||
, mTransferMouseDoubleClickEvent(false)
|
||||
, mTransferMouseMoveEvent(false)
|
||||
#ifndef QT_NO_WHEELEVENT
|
||||
, mTransferWheelEvent(false)
|
||||
#endif
|
||||
, mTransferEnterEvent(false)
|
||||
, mTransferLeaveEvent(false)
|
||||
{
|
||||
mContent->setParent(this);
|
||||
}
|
||||
|
||||
Qt::Corner RotatedWidget::origin() const
|
||||
{
|
||||
return mOrigin;
|
||||
}
|
||||
|
||||
void RotatedWidget::setOrigin(Qt::Corner newOrigin)
|
||||
{
|
||||
if (mOrigin != newOrigin)
|
||||
{
|
||||
if (mOrigin == Qt::TopLeftCorner)
|
||||
mContent->hide();
|
||||
|
||||
mOrigin = newOrigin;
|
||||
adjustContentSize();
|
||||
update();
|
||||
|
||||
if (mOrigin == Qt::TopLeftCorner)
|
||||
mContent->show();
|
||||
}
|
||||
}
|
||||
|
||||
QWidget * RotatedWidget::content() const
|
||||
{
|
||||
return mContent;
|
||||
}
|
||||
|
||||
void RotatedWidget::adjustContentSize()
|
||||
{
|
||||
mContent->adjustSize();
|
||||
|
||||
const QSize before = size();
|
||||
|
||||
adjustSize();
|
||||
|
||||
if (before != size())
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
QSize RotatedWidget::adjustedSize(QSize size) const
|
||||
{
|
||||
switch (mOrigin)
|
||||
{
|
||||
case Qt::TopLeftCorner:
|
||||
case Qt::BottomRightCorner:
|
||||
break;
|
||||
|
||||
case Qt::TopRightCorner:
|
||||
case Qt::BottomLeftCorner:
|
||||
size.transpose();
|
||||
break;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
QPoint RotatedWidget::adjustedPoint(QPoint point) const
|
||||
{
|
||||
switch (mOrigin)
|
||||
{
|
||||
case Qt::TopLeftCorner:
|
||||
case Qt::BottomRightCorner:
|
||||
break;
|
||||
|
||||
case Qt::TopRightCorner:
|
||||
case Qt::BottomLeftCorner:
|
||||
point = QPoint(point.y(), point.x());
|
||||
break;
|
||||
}
|
||||
|
||||
return point;
|
||||
}
|
||||
|
||||
QSize RotatedWidget::minimumSizeHint() const
|
||||
{
|
||||
return adjustedSize(mContent->minimumSizeHint());
|
||||
}
|
||||
|
||||
QSize RotatedWidget::sizeHint() const
|
||||
{
|
||||
return adjustedSize(mContent->sizeHint());
|
||||
}
|
||||
|
||||
void RotatedWidget::paintEvent(QPaintEvent */*event*/)
|
||||
{
|
||||
if (mOrigin == Qt::TopLeftCorner)
|
||||
return;
|
||||
|
||||
const QSize sz = mContent->size();
|
||||
|
||||
QPainter painter(this);
|
||||
|
||||
QTransform transform;
|
||||
QPoint originPoint;
|
||||
switch (mOrigin)
|
||||
{
|
||||
case Qt::TopLeftCorner:
|
||||
// transform.rotate(0.0);
|
||||
// originPoint = QPoint(0.0, 0.0);
|
||||
break;
|
||||
|
||||
case Qt::TopRightCorner:
|
||||
transform.rotate(90.0);
|
||||
originPoint = QPoint(0.0, -sz.height());
|
||||
break;
|
||||
|
||||
case Qt::BottomRightCorner:
|
||||
transform.rotate(180.0);
|
||||
originPoint = QPoint(-sz.width(), -sz.height());
|
||||
break;
|
||||
|
||||
case Qt::BottomLeftCorner:
|
||||
transform.rotate(270.0);
|
||||
originPoint = QPoint(-sz.width(), 0.0);
|
||||
break;
|
||||
}
|
||||
painter.setTransform(transform);
|
||||
mContent->render(&painter, originPoint, QRegion(), RenderFlags(DrawChildren));
|
||||
}
|
||||
|
||||
void RotatedWidget::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (!mTransferMousePressEvent)
|
||||
{
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
static bool cascadeCall = false;
|
||||
if (cascadeCall)
|
||||
return;
|
||||
cascadeCall = true;
|
||||
|
||||
QMouseEvent contentEvent(event->type(), adjustedPoint(event->pos()), event->globalPos(), event->button(), event->buttons(), event->modifiers());
|
||||
QApplication::sendEvent(mContent, &contentEvent);
|
||||
|
||||
cascadeCall = false;
|
||||
}
|
||||
|
||||
void RotatedWidget::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
if (!mTransferMouseReleaseEvent)
|
||||
{
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
static bool cascadeCall = false;
|
||||
if (cascadeCall)
|
||||
return;
|
||||
cascadeCall = true;
|
||||
|
||||
QMouseEvent contentEvent(event->type(), adjustedPoint(event->pos()), event->globalPos(), event->button(), event->buttons(), event->modifiers());
|
||||
QApplication::sendEvent(mContent, &contentEvent);
|
||||
|
||||
cascadeCall = false;
|
||||
}
|
||||
|
||||
void RotatedWidget::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
{
|
||||
if (!mTransferMouseDoubleClickEvent)
|
||||
{
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
static bool cascadeCall = false;
|
||||
if (cascadeCall)
|
||||
return;
|
||||
cascadeCall = true;
|
||||
|
||||
QMouseEvent contentEvent(event->type(), adjustedPoint(event->pos()), event->globalPos(), event->button(), event->buttons(), event->modifiers());
|
||||
QApplication::sendEvent(mContent, &contentEvent);
|
||||
|
||||
cascadeCall = false;
|
||||
}
|
||||
|
||||
void RotatedWidget::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
if (!mTransferMouseMoveEvent)
|
||||
{
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
static bool cascadeCall = false;
|
||||
if (cascadeCall)
|
||||
return;
|
||||
cascadeCall = true;
|
||||
|
||||
QMouseEvent contentEvent(event->type(), adjustedPoint(event->pos()), event->globalPos(), event->button(), event->buttons(), event->modifiers());
|
||||
QApplication::sendEvent(mContent, &contentEvent);
|
||||
|
||||
cascadeCall = false;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_WHEELEVENT
|
||||
void RotatedWidget::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
if (!mTransferWheelEvent)
|
||||
{
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
static bool cascadeCall = false;
|
||||
if (cascadeCall)
|
||||
return;
|
||||
cascadeCall = true;
|
||||
|
||||
QWheelEvent contentEvent(adjustedPoint(event->pos()), event->globalPos(), event->delta(), event->buttons(), event->modifiers(), event->orientation());
|
||||
QApplication::sendEvent(mContent, &contentEvent);
|
||||
|
||||
cascadeCall = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
void RotatedWidget::enterEvent(QEvent *event)
|
||||
{
|
||||
if (!mTransferEnterEvent)
|
||||
{
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
static bool cascadeCall = false;
|
||||
if (cascadeCall)
|
||||
return;
|
||||
cascadeCall = true;
|
||||
|
||||
QApplication::sendEvent(mContent, event);
|
||||
|
||||
cascadeCall = false;
|
||||
}
|
||||
|
||||
void RotatedWidget::leaveEvent(QEvent *event)
|
||||
{
|
||||
if (!mTransferLeaveEvent)
|
||||
{
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
static bool cascadeCall = false;
|
||||
if (cascadeCall)
|
||||
return;
|
||||
cascadeCall = true;
|
||||
|
||||
QApplication::sendEvent(mContent, event);
|
||||
|
||||
cascadeCall = false;
|
||||
}
|
||||
|
||||
void RotatedWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
static bool cascadeCall = false;
|
||||
if (cascadeCall)
|
||||
return;
|
||||
cascadeCall = true;
|
||||
|
||||
QResizeEvent contentEvent(adjustedSize(event->size()), adjustedSize(event->oldSize()));
|
||||
QApplication::sendEvent(mContent, &contentEvent);
|
||||
|
||||
cascadeCall = false;
|
||||
}
|
@ -1,126 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright: 2010-2013 Razor team
|
||||
* Authors:
|
||||
* Kuzma Shapran <kuzma.shapran@gmail.com>
|
||||
*
|
||||
* This program or library is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
#ifndef LXQTROTATED_WIDGET_H
|
||||
#define LXQTROTATED_WIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include "lxqtglobals.h"
|
||||
|
||||
namespace LXQt
|
||||
{
|
||||
|
||||
class LXQT_API RotatedWidget: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(Qt::Corner origin READ origin WRITE setOrigin)
|
||||
|
||||
Q_PROPERTY(bool transferMousePressEvent READ transferMousePressEvent WRITE setTransferMousePressEvent)
|
||||
Q_PROPERTY(bool transferMouseReleaseEvent READ transferMouseReleaseEvent WRITE setTransferMouseReleaseEvent)
|
||||
Q_PROPERTY(bool transferMouseDoubleClickEvent READ transferMouseDoubleClickEvent WRITE setTransferMouseDoubleClickEvent)
|
||||
Q_PROPERTY(bool transferMouseMoveEvent READ transferMouseMoveEvent WRITE setTransferMouseMoveEvent)
|
||||
#ifndef QT_NO_WHEELEVENT
|
||||
Q_PROPERTY(bool transferWheelEvent READ transferWheelEvent WRITE setTransferWheelEvent)
|
||||
#endif
|
||||
|
||||
Q_PROPERTY(bool transferEnterEvent READ transferEnterEvent WRITE setTransferEnterEvent)
|
||||
Q_PROPERTY(bool transferLeaveEvent READ transferLeaveEvent WRITE setTransferLeaveEvent)
|
||||
|
||||
public:
|
||||
explicit RotatedWidget(QWidget &content, QWidget* parent = 0, Qt::WindowFlags f = 0);
|
||||
|
||||
Qt::Corner origin() const;
|
||||
void setOrigin(Qt::Corner);
|
||||
|
||||
QWidget * content() const;
|
||||
|
||||
void adjustContentSize();
|
||||
|
||||
virtual QSize minimumSizeHint() const;
|
||||
virtual QSize sizeHint() const;
|
||||
|
||||
QSize adjustedSize(QSize) const;
|
||||
QPoint adjustedPoint(QPoint) const;
|
||||
|
||||
|
||||
bool transferMousePressEvent() const { return mTransferMousePressEvent; }
|
||||
void setTransferMousePressEvent(bool value) { mTransferMousePressEvent = value; }
|
||||
|
||||
bool transferMouseReleaseEvent() const { return mTransferMouseReleaseEvent; }
|
||||
void setTransferMouseReleaseEvent(bool value) { mTransferMouseReleaseEvent = value; }
|
||||
|
||||
bool transferMouseDoubleClickEvent() const { return mTransferMouseDoubleClickEvent; }
|
||||
void setTransferMouseDoubleClickEvent(bool value) { mTransferMouseDoubleClickEvent = value; }
|
||||
|
||||
bool transferMouseMoveEvent() const { return mTransferMouseMoveEvent; }
|
||||
void setTransferMouseMoveEvent(bool value) { mTransferMouseMoveEvent = value; }
|
||||
|
||||
#ifndef QT_NO_WHEELEVENT
|
||||
bool transferWheelEvent() const { return mTransferWheelEvent; }
|
||||
void setTransferWheelEvent(bool value) { mTransferWheelEvent = value; }
|
||||
#endif
|
||||
|
||||
bool transferEnterEvent() const { return mTransferEnterEvent; }
|
||||
void setTransferEnterEvent(bool value) { mTransferEnterEvent = value; }
|
||||
|
||||
bool transferLeaveEvent() const { return mTransferLeaveEvent; }
|
||||
void setTransferLeaveEvent(bool value) { mTransferLeaveEvent = value; }
|
||||
|
||||
protected:
|
||||
virtual void paintEvent(QPaintEvent *);
|
||||
|
||||
// Transition event handlers
|
||||
virtual void mousePressEvent(QMouseEvent *);
|
||||
virtual void mouseReleaseEvent(QMouseEvent *);
|
||||
virtual void mouseDoubleClickEvent(QMouseEvent *);
|
||||
virtual void mouseMoveEvent(QMouseEvent *);
|
||||
#ifndef QT_NO_WHEELEVENT
|
||||
virtual void wheelEvent(QWheelEvent *);
|
||||
#endif
|
||||
virtual void enterEvent(QEvent *);
|
||||
virtual void leaveEvent(QEvent *);
|
||||
|
||||
virtual void resizeEvent(QResizeEvent *);
|
||||
|
||||
private:
|
||||
QWidget *mContent;
|
||||
Qt::Corner mOrigin;
|
||||
|
||||
bool mTransferMousePressEvent;
|
||||
bool mTransferMouseReleaseEvent;
|
||||
bool mTransferMouseDoubleClickEvent;
|
||||
bool mTransferMouseMoveEvent;
|
||||
#ifndef QT_NO_WHEELEVENT
|
||||
bool mTransferWheelEvent;
|
||||
#endif
|
||||
bool mTransferEnterEvent;
|
||||
bool mTransferLeaveEvent;
|
||||
};
|
||||
|
||||
} // namespace LXQt
|
||||
#endif // LXQTROTATEDWIDGET_H
|
@ -1,252 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright: 2010-2011 Razor team
|
||||
* Authors:
|
||||
* Petr Vanek <petr@scribus.info>
|
||||
* Copyright (c) 2016 Luís Pereira <luis.artur.pereira@gmail.com>
|
||||
* Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
*
|
||||
* This program or library is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
#include <QProcess>
|
||||
#include "lxqtscreensaver.h"
|
||||
#include "lxqttranslator.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <XdgIcon>
|
||||
#include <QMessageBox>
|
||||
#include <QAction>
|
||||
#include <QPointer>
|
||||
#include <QProcess>
|
||||
#include <QCoreApplication> // for Q_DECLARE_TR_FUNCTIONS
|
||||
#include <QX11Info>
|
||||
|
||||
#include <X11/extensions/scrnsaver.h>
|
||||
|
||||
// Avoid polluting everything with X11/Xlib.h:
|
||||
typedef struct _XDisplay Display;
|
||||
|
||||
typedef unsigned long XAtom;
|
||||
typedef unsigned long XID;
|
||||
|
||||
extern "C" {
|
||||
int XFree(void*);
|
||||
}
|
||||
|
||||
template <class T, class R, R (*F)(T*)>
|
||||
struct XObjectDeleter {
|
||||
inline void operator()(void* ptr) const { F(static_cast<T*>(ptr)); }
|
||||
};
|
||||
|
||||
template <class T, class D = XObjectDeleter<void, int, XFree>>
|
||||
using XScopedPtr = std::unique_ptr<T, D>;
|
||||
|
||||
|
||||
namespace LXQt {
|
||||
|
||||
static bool GetProperty(XID window, const std::string& property_name, long max_length,
|
||||
Atom* type, int* format, unsigned long* num_items,
|
||||
unsigned char** property);
|
||||
|
||||
|
||||
static bool GetIntArrayProperty(XID window,
|
||||
const std::string& property_name,
|
||||
std::vector<int>* value);
|
||||
|
||||
|
||||
static bool GetProperty(XID window, const std::string& property_name, long max_length,
|
||||
Atom* type, int* format, unsigned long* num_items,
|
||||
unsigned char** property)
|
||||
{
|
||||
Atom property_atom = XInternAtom(QX11Info::display(), property_name.c_str(), false);
|
||||
unsigned long remaining_bytes = 0;
|
||||
return XGetWindowProperty(QX11Info::display(),
|
||||
window,
|
||||
property_atom,
|
||||
0, // offset into property data to read
|
||||
max_length, // max length to get
|
||||
False, // deleted
|
||||
AnyPropertyType,
|
||||
type,
|
||||
format,
|
||||
num_items,
|
||||
&remaining_bytes,
|
||||
property);
|
||||
}
|
||||
|
||||
static bool GetIntArrayProperty(XID window,
|
||||
const std::string& property_name,
|
||||
std::vector<int>* value)
|
||||
{
|
||||
Atom type = None;
|
||||
int format = 0; // size in bits of each item in 'property'
|
||||
unsigned long num_items = 0;
|
||||
unsigned char* properties = NULL;
|
||||
|
||||
int result = GetProperty(window, property_name,
|
||||
(~0L), // (all of them)
|
||||
&type, &format, &num_items, &properties);
|
||||
XScopedPtr<unsigned char> scoped_properties(properties);
|
||||
if (result != Success)
|
||||
return false;
|
||||
|
||||
if (format != 32)
|
||||
return false;
|
||||
|
||||
long* int_properties = reinterpret_cast<long*>(properties);
|
||||
value->clear();
|
||||
for (unsigned long i = 0; i < num_items; ++i)
|
||||
{
|
||||
value->push_back(static_cast<int>(int_properties[i]));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
class ScreenSaverPrivate
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(LXQt::ScreenSaver)
|
||||
Q_DECLARE_PUBLIC(ScreenSaver)
|
||||
ScreenSaver* const q_ptr;
|
||||
|
||||
public:
|
||||
ScreenSaverPrivate(ScreenSaver *q) : q_ptr(q) {};
|
||||
|
||||
void _l_xdgProcess_finished(int, QProcess::ExitStatus);
|
||||
bool isScreenSaverLocked();
|
||||
|
||||
QPointer<QProcess> m_xdgProcess;
|
||||
};
|
||||
|
||||
void ScreenSaverPrivate::_l_xdgProcess_finished(int err, QProcess::ExitStatus status)
|
||||
{
|
||||
// http://portland.freedesktop.org/xdg-utils-1.1.0-rc1/scripts/xdg-screensaver
|
||||
|
||||
Q_UNUSED(status)
|
||||
Q_Q(ScreenSaver);
|
||||
if (err == 0)
|
||||
emit q->activated();
|
||||
else
|
||||
{
|
||||
QMessageBox *box = new QMessageBox;
|
||||
box->setAttribute(Qt::WA_DeleteOnClose);
|
||||
box->setIcon(QMessageBox::Warning);
|
||||
|
||||
if (err == 1)
|
||||
{
|
||||
box->setWindowTitle(tr("Screen Saver Error"));
|
||||
box->setText(tr("An error occurred starting screensaver. "
|
||||
"Syntax error in xdg-screensaver arguments."));
|
||||
}
|
||||
else if (err == 3)
|
||||
{
|
||||
box->setWindowTitle(tr("Screen Saver Activation Error"));
|
||||
box->setText(tr("An error occurred starting screensaver. "
|
||||
"Ensure you have xscreensaver installed and running."));
|
||||
}
|
||||
else if (err == 4)
|
||||
{
|
||||
box->setWindowTitle(tr("Screen Saver Activation Error"));
|
||||
box->setText(tr("An error occurred starting screensaver. "
|
||||
"Action 'activate' failed. "
|
||||
"Ensure you have xscreensaver installed and running."));
|
||||
}
|
||||
else
|
||||
{
|
||||
box->setWindowTitle(tr("Screen Saver Activation Error"));
|
||||
box->setText(tr("An error occurred starting screensaver. "
|
||||
"Unknown error - undocumented return value from xdg-screensaver: %1.")
|
||||
.arg(err));
|
||||
}
|
||||
|
||||
box->exec();
|
||||
}
|
||||
|
||||
emit q->done();
|
||||
}
|
||||
|
||||
bool ScreenSaverPrivate::isScreenSaverLocked()
|
||||
{
|
||||
XScreenSaverInfo *info = 0;
|
||||
Display *display = QX11Info::display();
|
||||
XID window = DefaultRootWindow(display);
|
||||
info = XScreenSaverAllocInfo();
|
||||
|
||||
XScreenSaverQueryInfo(QX11Info::display(), window, info);
|
||||
const int state = info->state;
|
||||
XFree(info);
|
||||
if (state == ScreenSaverOn)
|
||||
return true;
|
||||
|
||||
// Ironically, xscreensaver does not conform to the XScreenSaver protocol, so
|
||||
// info.state == ScreenSaverOff or info.state == ScreenSaverDisabled does not
|
||||
// necessarily mean that a screensaver is not active, so add a special check
|
||||
// for xscreensaver.
|
||||
XAtom lock_atom = XInternAtom(display, "LOCK", false);
|
||||
std::vector<int> atom_properties;
|
||||
if (GetIntArrayProperty(window, "_SCREENSAVER_STATUS", &atom_properties) &&
|
||||
atom_properties.size() > 0)
|
||||
{
|
||||
if (atom_properties[0] == static_cast<int>(lock_atom))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ScreenSaver::ScreenSaver(QObject * parent)
|
||||
: QObject(parent),
|
||||
d_ptr(new ScreenSaverPrivate(this))
|
||||
{
|
||||
Q_D(ScreenSaver);
|
||||
d->m_xdgProcess = new QProcess(this);
|
||||
connect(d->m_xdgProcess, SIGNAL(finished(int,QProcess::ExitStatus)),
|
||||
this, SLOT(_l_xdgProcess_finished(int,QProcess::ExitStatus)));
|
||||
}
|
||||
|
||||
ScreenSaver::~ScreenSaver()
|
||||
{
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
QList<QAction*> ScreenSaver::availableActions()
|
||||
{
|
||||
QList<QAction*> ret;
|
||||
QAction * act;
|
||||
|
||||
act = new QAction(XdgIcon::fromTheme("system-lock-screen", "lock"), tr("Lock Screen"), this);
|
||||
connect(act, SIGNAL(triggered()), this, SLOT(lockScreen()));
|
||||
ret.append(act);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ScreenSaver::lockScreen()
|
||||
{
|
||||
Q_D(ScreenSaver);
|
||||
if (!d->isScreenSaverLocked())
|
||||
d->m_xdgProcess->start("xdg-screensaver", QStringList() << "lock");
|
||||
}
|
||||
|
||||
} // namespace LXQt
|
||||
|
||||
#include "moc_lxqtscreensaver.cpp"
|
@ -1,68 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright: 2010-2011 Razor team
|
||||
* Authors:
|
||||
* Petr Vanek <petr@scribus.info>
|
||||
*
|
||||
* Copyright (c) 2016 Luís Pereira <luis.artur.pereira@gmail.com>
|
||||
*
|
||||
* This program or library is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
#ifndef SCREENSAVER_H
|
||||
#define SCREENSAVER_H
|
||||
|
||||
#include "lxqtglobals.h"
|
||||
#include <QObject>
|
||||
#include <QAction>
|
||||
|
||||
namespace LXQt
|
||||
{
|
||||
|
||||
class ScreenSaverPrivate;
|
||||
|
||||
class LXQT_API ScreenSaver : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_DECLARE_PRIVATE(ScreenSaver)
|
||||
Q_DISABLE_COPY(ScreenSaver)
|
||||
|
||||
public:
|
||||
ScreenSaver(QObject * parent=0);
|
||||
~ScreenSaver();
|
||||
|
||||
QList<QAction*> availableActions();
|
||||
|
||||
signals:
|
||||
void activated();
|
||||
void done();
|
||||
public slots:
|
||||
void lockScreen();
|
||||
|
||||
private:
|
||||
ScreenSaverPrivate* const d_ptr;
|
||||
|
||||
Q_PRIVATE_SLOT(d_func(), void _l_xdgProcess_finished(int, QProcess::ExitStatus))
|
||||
};
|
||||
|
||||
} // namespace LXQt
|
||||
#endif
|
||||
|
@ -1,744 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright: 2010-2011 Razor team
|
||||
* Authors:
|
||||
* Alexander Sokoloff <sokoloff.a@gmail.com>
|
||||
* Petr Vanek <petr@scribus.info>
|
||||
*
|
||||
* This program or library is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
#include "lxqtsettings.h"
|
||||
#include <QDebug>
|
||||
#include <QEvent>
|
||||
#include <QDir>
|
||||
#include <QStringList>
|
||||
#include <QMutex>
|
||||
#include <QFileSystemWatcher>
|
||||
#include <QSharedData>
|
||||
#include <QTimerEvent>
|
||||
|
||||
#include <XdgDirs>
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 6, 0)
|
||||
#include <algorithm>
|
||||
#endif
|
||||
|
||||
using namespace LXQt;
|
||||
|
||||
class LXQt::SettingsPrivate
|
||||
{
|
||||
public:
|
||||
SettingsPrivate(Settings* parent, bool useXdgFallback):
|
||||
mFileChangeTimer(0),
|
||||
mAppChangeTimer(0),
|
||||
mAddWatchTimer(0),
|
||||
mParent(parent)
|
||||
{
|
||||
// HACK: we need to ensure that the user (~/.config/lxqt/<module>.conf)
|
||||
// exists to have functional mWatcher
|
||||
if (!mParent->contains("__userfile__"))
|
||||
{
|
||||
mParent->setValue("__userfile__", true);
|
||||
#if defined(WITH_XDG_DIRS_FALLBACK)
|
||||
if (useXdgFallback)
|
||||
{
|
||||
//Note: Qt doesn't support the xdg spec regarding the XDG_CONFIG_DIRS
|
||||
//https://bugreports.qt.io/browse/QTBUG-34919
|
||||
//(Partial) workaround: if the the user specific config file doesn't exist
|
||||
//we try to find some system-wide configuration file and copy all settings into
|
||||
//the user specific file
|
||||
const QString org = mParent->organizationName();
|
||||
const QString file_name = QFileInfo{mParent->fileName()}.fileName();
|
||||
QStringList dirs = XdgDirs::configDirs();
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 6, 0)
|
||||
std::reverse(dirs.begin(), dirs.end());
|
||||
for (auto dir_i = dirs.begin(), dir_e = dirs.end(); dir_i != dir_e; ++dir_i)
|
||||
#else // QT_VERSION
|
||||
for (auto dir_i = dirs.rbegin(), dir_e = dirs.rend(); dir_i != dir_e; ++dir_i)
|
||||
#endif
|
||||
|
||||
{
|
||||
QDir dir{*dir_i};
|
||||
if (dir.cd(mParent->organizationName()) && dir.exists(file_name))
|
||||
{
|
||||
QSettings system_settings{dir.absoluteFilePath(file_name), QSettings::IniFormat};
|
||||
const QStringList keys = system_settings.allKeys();
|
||||
for (const QString & key : keys)
|
||||
{
|
||||
mParent->setValue(key, system_settings.value(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
mParent->sync();
|
||||
}
|
||||
mWatcher.addPath(mParent->fileName());
|
||||
QObject::connect(&(mWatcher), &QFileSystemWatcher::fileChanged, mParent, &Settings::_fileChanged);
|
||||
}
|
||||
|
||||
QString localizedKey(const QString& key) const;
|
||||
|
||||
QFileSystemWatcher mWatcher;
|
||||
int mFileChangeTimer;
|
||||
int mAppChangeTimer;
|
||||
int mAddWatchTimer;
|
||||
|
||||
private:
|
||||
Settings* mParent;
|
||||
};
|
||||
|
||||
|
||||
LXQtTheme* LXQtTheme::mInstance = 0;
|
||||
|
||||
class LXQt::LXQtThemeData: public QSharedData {
|
||||
public:
|
||||
LXQtThemeData(): mValid(false) {}
|
||||
QString loadQss(const QString& qssFile) const;
|
||||
QString findTheme(const QString &themeName);
|
||||
|
||||
QString mName;
|
||||
QString mPath;
|
||||
QString mPreviewImg;
|
||||
bool mValid;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class LXQt::GlobalSettingsPrivate
|
||||
{
|
||||
public:
|
||||
GlobalSettingsPrivate(GlobalSettings *parent):
|
||||
mParent(parent),
|
||||
mThemeUpdated(0ull)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
GlobalSettings *mParent;
|
||||
QString mIconTheme;
|
||||
QString mLXQtTheme;
|
||||
qlonglong mThemeUpdated;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
Settings::Settings(const QString& module, QObject* parent) :
|
||||
QSettings("lxqt", module, parent),
|
||||
d_ptr(new SettingsPrivate(this, true))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
Settings::Settings(const QString &fileName, QSettings::Format format, QObject *parent):
|
||||
QSettings(fileName, format, parent),
|
||||
d_ptr(new SettingsPrivate(this, false))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
Settings::Settings(const QSettings* parentSettings, const QString& subGroup, QObject* parent):
|
||||
QSettings(parentSettings->organizationName(), parentSettings->applicationName(), parent),
|
||||
d_ptr(new SettingsPrivate(this, false))
|
||||
{
|
||||
beginGroup(subGroup);
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
Settings::Settings(const QSettings& parentSettings, const QString& subGroup, QObject* parent):
|
||||
QSettings(parentSettings.organizationName(), parentSettings.applicationName(), parent),
|
||||
d_ptr(new SettingsPrivate(this, false))
|
||||
{
|
||||
beginGroup(subGroup);
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
Settings::~Settings()
|
||||
{
|
||||
// because in the Settings::Settings(const QString& module, QObject* parent)
|
||||
// constructor there is no beginGroup() called...
|
||||
if (!group().isEmpty())
|
||||
endGroup();
|
||||
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
bool Settings::event(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::UpdateRequest)
|
||||
{
|
||||
// delay the settingsChanged* signal emitting for:
|
||||
// - checking in _fileChanged
|
||||
// - merging emitting the signals
|
||||
if(d_ptr->mAppChangeTimer)
|
||||
killTimer(d_ptr->mAppChangeTimer);
|
||||
d_ptr->mAppChangeTimer = startTimer(100);
|
||||
}
|
||||
else if (event->type() == QEvent::Timer)
|
||||
{
|
||||
const int timer = static_cast<QTimerEvent*>(event)->timerId();
|
||||
killTimer(timer);
|
||||
if (timer == d_ptr->mFileChangeTimer)
|
||||
{
|
||||
d_ptr->mFileChangeTimer = 0;
|
||||
fileChanged(); // invoke the real fileChanged() handler.
|
||||
} else if (timer == d_ptr->mAppChangeTimer)
|
||||
{
|
||||
d_ptr->mAppChangeTimer = 0;
|
||||
// do emit the signals
|
||||
emit settingsChangedByApp();
|
||||
emit settingsChanged();
|
||||
} else if (timer == d_ptr->mAddWatchTimer)
|
||||
{
|
||||
d_ptr->mAddWatchTimer = 0;
|
||||
//try to re-add filename for watching
|
||||
addWatchedFile(fileName());
|
||||
}
|
||||
}
|
||||
|
||||
return QSettings::event(event);
|
||||
}
|
||||
|
||||
void Settings::fileChanged()
|
||||
{
|
||||
sync();
|
||||
emit settingsChangedFromExternal();
|
||||
emit settingsChanged();
|
||||
}
|
||||
|
||||
void Settings::_fileChanged(QString path)
|
||||
{
|
||||
// check if the file isn't changed by our logic
|
||||
// FIXME: this is poor implementation; should we rather compute some hash of values if changed by external?
|
||||
if (0 == d_ptr->mAppChangeTimer)
|
||||
{
|
||||
// delay the change notification for 100 ms to avoid
|
||||
// unnecessary repeated loading of the same config file if
|
||||
// the file is changed for several times rapidly.
|
||||
if(d_ptr->mFileChangeTimer)
|
||||
killTimer(d_ptr->mFileChangeTimer);
|
||||
d_ptr->mFileChangeTimer = startTimer(1000);
|
||||
}
|
||||
|
||||
addWatchedFile(path);
|
||||
}
|
||||
|
||||
void Settings::addWatchedFile(QString const & path)
|
||||
{
|
||||
// D*mn! yet another Qt 5.4 regression!!!
|
||||
// See the bug report: https://github.com/lxde/lxqt/issues/441
|
||||
// Since Qt 5.4, QSettings uses QSaveFile to save the config files.
|
||||
// https://github.com/qtproject/qtbase/commit/8d15068911d7c0ba05732e2796aaa7a90e34a6a1#diff-e691c0405f02f3478f4f50a27bdaecde
|
||||
// QSaveFile will save the content to a new temp file, and replace the old file later.
|
||||
// Hence the existing config file is not changed. Instead, it's deleted and then replaced.
|
||||
// This new behaviour unfortunately breaks QFileSystemWatcher.
|
||||
// After file deletion, we can no longer receive any new change notifications.
|
||||
// The most ridiculous thing is, QFileSystemWatcher does not provide a
|
||||
// way for us to know if a file is deleted. WT*?
|
||||
// Luckily, I found a workaround: If the file path no longer exists
|
||||
// in the watcher's files(), this file is deleted.
|
||||
if(!d_ptr->mWatcher.files().contains(path))
|
||||
// in some situations adding fails because of non-existing file (e.g. editting file in external program)
|
||||
if (!d_ptr->mWatcher.addPath(path) && 0 == d_ptr->mAddWatchTimer)
|
||||
d_ptr->mAddWatchTimer = startTimer(100);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
const GlobalSettings *Settings::globalSettings()
|
||||
{
|
||||
static QMutex mutex;
|
||||
static GlobalSettings *instance = 0;
|
||||
if (!instance)
|
||||
{
|
||||
mutex.lock();
|
||||
|
||||
if (!instance)
|
||||
instance = new GlobalSettings();
|
||||
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
LC_MESSAGES value Possible keys in order of matching
|
||||
lang_COUNTRY@MODIFIER lang_COUNTRY@MODIFIER, lang_COUNTRY, lang@MODIFIER, lang,
|
||||
default value
|
||||
lang_COUNTRY lang_COUNTRY, lang, default value
|
||||
lang@MODIFIER lang@MODIFIER, lang, default value
|
||||
lang lang, default value
|
||||
************************************************/
|
||||
QString SettingsPrivate::localizedKey(const QString& key) const
|
||||
{
|
||||
|
||||
QString lang = getenv("LC_MESSAGES");
|
||||
|
||||
if (lang.isEmpty())
|
||||
lang = getenv("LC_ALL");
|
||||
|
||||
if (lang.isEmpty())
|
||||
lang = getenv("LANG");
|
||||
|
||||
|
||||
QString modifier = lang.section('@', 1);
|
||||
if (!modifier.isEmpty())
|
||||
lang.truncate(lang.length() - modifier.length() - 1);
|
||||
|
||||
QString encoding = lang.section('.', 1);
|
||||
if (!encoding.isEmpty())
|
||||
lang.truncate(lang.length() - encoding.length() - 1);
|
||||
|
||||
|
||||
QString country = lang.section('_', 1);
|
||||
if (!country.isEmpty())
|
||||
lang.truncate(lang.length() - country.length() - 1);
|
||||
|
||||
|
||||
|
||||
//qDebug() << "LC_MESSAGES: " << getenv("LC_MESSAGES");
|
||||
//qDebug() << "Lang:" << lang;
|
||||
//qDebug() << "Country:" << country;
|
||||
//qDebug() << "Encoding:" << encoding;
|
||||
//qDebug() << "Modifier:" << modifier;
|
||||
|
||||
if (!modifier.isEmpty() && !country.isEmpty())
|
||||
{
|
||||
QString k = QString("%1[%2_%3@%4]").arg(key, lang, country, modifier);
|
||||
//qDebug() << "\t try " << k << mParent->contains(k);
|
||||
if (mParent->contains(k))
|
||||
return k;
|
||||
}
|
||||
|
||||
if (!country.isEmpty())
|
||||
{
|
||||
QString k = QString("%1[%2_%3]").arg(key, lang, country);
|
||||
//qDebug() << "\t try " << k << mParent->contains(k);
|
||||
if (mParent->contains(k))
|
||||
return k;
|
||||
}
|
||||
|
||||
if (!modifier.isEmpty())
|
||||
{
|
||||
QString k = QString("%1[%2@%3]").arg(key, lang, modifier);
|
||||
//qDebug() << "\t try " << k << mParent->contains(k);
|
||||
if (mParent->contains(k))
|
||||
return k;
|
||||
}
|
||||
|
||||
QString k = QString("%1[%2]").arg(key, lang);
|
||||
//qDebug() << "\t try " << k << mParent->contains(k);
|
||||
if (mParent->contains(k))
|
||||
return k;
|
||||
|
||||
|
||||
//qDebug() << "\t try " << key << mParent->contains(key);
|
||||
return key;
|
||||
}
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
QVariant Settings::localizedValue(const QString& key, const QVariant& defaultValue) const
|
||||
{
|
||||
Q_D(const Settings);
|
||||
return value(d->localizedKey(key), defaultValue);
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
void Settings::setLocalizedValue(const QString &key, const QVariant &value)
|
||||
{
|
||||
Q_D(const Settings);
|
||||
setValue(d->localizedKey(key), value);
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
LXQtTheme::LXQtTheme():
|
||||
d(new LXQtThemeData)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
LXQtTheme::LXQtTheme(const QString &path):
|
||||
d(new LXQtThemeData)
|
||||
{
|
||||
if (path.isEmpty())
|
||||
return;
|
||||
|
||||
QFileInfo fi(path);
|
||||
if (fi.isAbsolute())
|
||||
{
|
||||
d->mPath = path;
|
||||
d->mName = fi.fileName();
|
||||
d->mValid = fi.isDir();
|
||||
}
|
||||
else
|
||||
{
|
||||
d->mName = path;
|
||||
d->mPath = d->findTheme(path);
|
||||
d->mValid = !(d->mPath.isEmpty());
|
||||
}
|
||||
|
||||
if (QDir(path).exists("preview.png"))
|
||||
d->mPreviewImg = path + "/preview.png";
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
QString LXQtThemeData::findTheme(const QString &themeName)
|
||||
{
|
||||
if (themeName.isEmpty())
|
||||
return QString();
|
||||
|
||||
QStringList paths;
|
||||
QLatin1String fallback(LXQT_INSTALL_PREFIX);
|
||||
|
||||
paths << XdgDirs::dataHome(false);
|
||||
paths << XdgDirs::dataDirs();
|
||||
|
||||
if (!paths.contains(fallback))
|
||||
paths << fallback;
|
||||
|
||||
foreach(const QString &path, paths)
|
||||
{
|
||||
QDir dir(QString("%1/lxqt/themes/%2").arg(path, themeName));
|
||||
if (dir.isReadable())
|
||||
return dir.absolutePath();
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
LXQtTheme::LXQtTheme(const LXQtTheme &other):
|
||||
d(other.d)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
LXQtTheme::~LXQtTheme()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
LXQtTheme& LXQtTheme::operator=(const LXQtTheme &other)
|
||||
{
|
||||
d = other.d;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
bool LXQtTheme::isValid() const
|
||||
{
|
||||
return d->mValid;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
QString LXQtTheme::name() const
|
||||
{
|
||||
return d->mName;
|
||||
}
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
QString LXQtTheme::path() const
|
||||
{
|
||||
return d->mPath;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
QString LXQtTheme::previewImage() const
|
||||
{
|
||||
return d->mPreviewImg;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
QString LXQtTheme::qss(const QString& module) const
|
||||
{
|
||||
return d->loadQss(QStringLiteral("%1/%2.qss").arg(d->mPath, module));
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
QString LXQtThemeData::loadQss(const QString& qssFile) const
|
||||
{
|
||||
QFile f(qssFile);
|
||||
if (! f.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString qss = f.readAll();
|
||||
f.close();
|
||||
|
||||
if (qss.isEmpty())
|
||||
return QString();
|
||||
|
||||
// handle relative paths
|
||||
QString qssDir = QFileInfo(qssFile).canonicalPath();
|
||||
qss.replace(QRegExp("url.[ \\t\\s]*", Qt::CaseInsensitive, QRegExp::RegExp2), "url(" + qssDir + "/");
|
||||
|
||||
return qss;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
QString LXQtTheme::desktopBackground(int screen) const
|
||||
{
|
||||
QString wallpaperCfgFileName = QString("%1/wallpaper.cfg").arg(d->mPath);
|
||||
|
||||
if (wallpaperCfgFileName.isEmpty())
|
||||
return QString();
|
||||
|
||||
QSettings s(wallpaperCfgFileName, QSettings::IniFormat);
|
||||
QString themeDir = QFileInfo(wallpaperCfgFileName).absolutePath();
|
||||
// There is something strange... If I remove next line the wallpapers array is not found...
|
||||
s.childKeys();
|
||||
s.beginReadArray("wallpapers");
|
||||
|
||||
s.setArrayIndex(screen - 1);
|
||||
if (s.contains("file"))
|
||||
return QString("%1/%2").arg(themeDir, s.value("file").toString());
|
||||
|
||||
s.setArrayIndex(0);
|
||||
if (s.contains("file"))
|
||||
return QString("%1/%2").arg(themeDir, s.value("file").toString());
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
const LXQtTheme &LXQtTheme::currentTheme()
|
||||
{
|
||||
static LXQtTheme theme;
|
||||
QString name = Settings::globalSettings()->value("theme").toString();
|
||||
if (theme.name() != name)
|
||||
{
|
||||
theme = LXQtTheme(name);
|
||||
}
|
||||
return theme;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
QList<LXQtTheme> LXQtTheme::allThemes()
|
||||
{
|
||||
QList<LXQtTheme> ret;
|
||||
QSet<QString> processed;
|
||||
|
||||
QStringList paths;
|
||||
paths << XdgDirs::dataHome(false);
|
||||
paths << XdgDirs::dataDirs();
|
||||
|
||||
foreach(const QString &path, paths)
|
||||
{
|
||||
QDir dir(QString("%1/lxqt/themes").arg(path));
|
||||
QFileInfoList dirs = dir.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot);
|
||||
|
||||
foreach(const QFileInfo &dir, dirs)
|
||||
{
|
||||
if (!processed.contains(dir.fileName()) &&
|
||||
QDir(dir.absoluteFilePath()).exists("lxqt-panel.qss"))
|
||||
{
|
||||
processed << dir.fileName();
|
||||
ret << LXQtTheme(dir.absoluteFilePath());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
SettingsCache::SettingsCache(QSettings &settings) :
|
||||
mSettings(settings)
|
||||
{
|
||||
loadFromSettings();
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
SettingsCache::SettingsCache(QSettings *settings) :
|
||||
mSettings(*settings)
|
||||
{
|
||||
loadFromSettings();
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
void SettingsCache::loadFromSettings()
|
||||
{
|
||||
const QStringList keys = mSettings.allKeys();
|
||||
|
||||
const int N = keys.size();
|
||||
for (int i = 0; i < N; ++i) {
|
||||
mCache.insert(keys.at(i), mSettings.value(keys.at(i)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
void SettingsCache::loadToSettings()
|
||||
{
|
||||
QHash<QString, QVariant>::const_iterator i = mCache.constBegin();
|
||||
|
||||
while(i != mCache.constEnd())
|
||||
{
|
||||
mSettings.setValue(i.key(), i.value());
|
||||
++i;
|
||||
}
|
||||
|
||||
mSettings.sync();
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
GlobalSettings::GlobalSettings():
|
||||
Settings("lxqt"),
|
||||
d_ptr(new GlobalSettingsPrivate(this))
|
||||
{
|
||||
if (value("icon_theme").toString().isEmpty())
|
||||
{
|
||||
qWarning() << QString::fromLatin1("Icon Theme not set. Fallbacking to Oxygen, if installed");
|
||||
const QString fallback(QLatin1String("oxygen"));
|
||||
|
||||
const QDir dir(QLatin1String(LXQT_DATA_DIR) + QLatin1String("/icons"));
|
||||
if (dir.exists(fallback))
|
||||
{
|
||||
setValue("icon_theme", fallback);
|
||||
sync();
|
||||
}
|
||||
else
|
||||
{
|
||||
qWarning() << QString::fromLatin1("Fallback Icon Theme (Oxygen) not found");
|
||||
}
|
||||
}
|
||||
|
||||
fileChanged();
|
||||
}
|
||||
|
||||
GlobalSettings::~GlobalSettings()
|
||||
{
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
void GlobalSettings::fileChanged()
|
||||
{
|
||||
Q_D(GlobalSettings);
|
||||
sync();
|
||||
|
||||
|
||||
QString it = value("icon_theme").toString();
|
||||
if (d->mIconTheme != it)
|
||||
{
|
||||
emit iconThemeChanged();
|
||||
}
|
||||
|
||||
QString rt = value("theme").toString();
|
||||
qlonglong themeUpdated = value("__theme_updated__").toLongLong();
|
||||
if ((d->mLXQtTheme != rt) || (d->mThemeUpdated != themeUpdated))
|
||||
{
|
||||
d->mLXQtTheme = rt;
|
||||
emit lxqtThemeChanged();
|
||||
}
|
||||
|
||||
emit settingsChangedFromExternal();
|
||||
emit settingsChanged();
|
||||
}
|
||||
|
@ -1,217 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright: 2010-2011 Razor team
|
||||
* Authors:
|
||||
* Alexander Sokoloff <sokoloff.a@gmail.com>
|
||||
*
|
||||
* This program or library is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
|
||||
#ifndef LXQTSETTINGS_H
|
||||
#define LXQTSETTINGS_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QSettings>
|
||||
#include <QSharedDataPointer>
|
||||
#include "lxqtglobals.h"
|
||||
|
||||
class QEvent;
|
||||
|
||||
namespace LXQt
|
||||
{
|
||||
|
||||
class SettingsPrivate;
|
||||
class GlobalSettings;
|
||||
|
||||
/*! \brief User settings handling */
|
||||
class LXQT_API Settings : public QSettings
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
/*! \brief Constructs a Settings object for accessing settings of the module called module, and with parent parent.
|
||||
Settings can be accessed using the standard interface provided by QSettings, but it also provides some convenience functions and signals.
|
||||
|
||||
\param module a base name of the config file. It's a name without
|
||||
the extension. For example: if you want to open settings for
|
||||
panel create it as Settings("panel").
|
||||
The function will create all parent directories necessary to create
|
||||
the file.
|
||||
\param parent It's no need to delete this class manually if it's set.
|
||||
*/
|
||||
explicit Settings(const QString& module, QObject* parent = 0);
|
||||
//explicit Settings(QObject* parent=0);
|
||||
explicit Settings(const QSettings* parentSettings, const QString& subGroup, QObject* parent=0);
|
||||
explicit Settings(const QSettings& parentSettings, const QString& subGroup, QObject* parent=0);
|
||||
Settings(const QString &fileName, QSettings::Format format, QObject *parent = 0);
|
||||
~Settings();
|
||||
|
||||
static const GlobalSettings *globalSettings();
|
||||
|
||||
|
||||
/*! Returns the localized value for key. In the desktop file keys may be postfixed by [LOCALE]. If the
|
||||
localized value doesn't exist, returns non lokalized value. If non localized value doesn't exist, returns defaultValue.
|
||||
LOCALE must be of the form lang_COUNTRY.ENCODING@MODIFIER, where _COUNTRY, .ENCODING, and @MODIFIER may be omitted.
|
||||
|
||||
If no default value is specified, a default QVariant is returned. */
|
||||
QVariant localizedValue(const QString& key, const QVariant& defaultValue = QVariant()) const;
|
||||
|
||||
/*! Sets the value of setting key to value. If a localized version of the key already exists, the previous value is
|
||||
overwritten. Otherwise, it overwrites the the un-localized version. */
|
||||
void setLocalizedValue(const QString &key, const QVariant &value);
|
||||
|
||||
signals:
|
||||
/*! /brief signal for backward compatibility (emitted whenever settingsChangedFromExternal() or settingsChangedByApp() is emitted)
|
||||
*/
|
||||
void settingsChanged();
|
||||
/*! /brief signal emitted when the settings file is changed by external application
|
||||
*/
|
||||
void settingsChangedFromExternal();
|
||||
/*! /brief signal emitted when any setting is changed by this object
|
||||
*/
|
||||
void settingsChangedByApp();
|
||||
|
||||
protected:
|
||||
bool event(QEvent *event);
|
||||
|
||||
protected slots:
|
||||
/*! Called when the config file is changed */
|
||||
virtual void fileChanged();
|
||||
|
||||
private slots:
|
||||
void _fileChanged(QString path);
|
||||
|
||||
private:
|
||||
void addWatchedFile(QString const & path);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(Settings)
|
||||
|
||||
SettingsPrivate* const d_ptr;
|
||||
Q_DECLARE_PRIVATE(Settings)
|
||||
};
|
||||
|
||||
|
||||
class LXQtThemeData;
|
||||
|
||||
/*! \brief QSS theme handling */
|
||||
class LXQT_API LXQtTheme
|
||||
{
|
||||
public:
|
||||
/// Constructs a null theme.
|
||||
LXQtTheme();
|
||||
|
||||
/*! Constructs an theme from the dir with the given path. If path not absolute
|
||||
(i.e. the theme name only) the relevant dir must be found relative to the
|
||||
$XDG_DATA_HOME + $XDG_DATA_DIRS directories. */
|
||||
LXQtTheme(const QString &path);
|
||||
|
||||
/// Constructs a copy of other. This is very fast.
|
||||
LXQtTheme(const LXQtTheme &other);
|
||||
|
||||
LXQtTheme& operator=(const LXQtTheme &other);
|
||||
~LXQtTheme();
|
||||
|
||||
/// Returns the name of the theme.
|
||||
QString name() const;
|
||||
|
||||
QString path() const;
|
||||
|
||||
QString previewImage() const;
|
||||
|
||||
/// Returns true if this theme is valid; otherwise returns false.
|
||||
bool isValid() const;
|
||||
|
||||
/*! \brief Returns StyleSheet text (not file name, but real text) of the module called module.
|
||||
Paths in url() C/QSS functions are parsed to be real values for the theme,
|
||||
relative to full path
|
||||
*/
|
||||
QString qss(const QString& module) const;
|
||||
|
||||
/*! \brief A full path to image used as a wallpaper
|
||||
\param screen is an ID of the screen like in Qt. -1 means default (any) screen.
|
||||
Any other value greater than -1 is the exact screen (in dualhead).
|
||||
In themes the index starts from 1 (ix 1 means 1st screen).
|
||||
\retval QString a file name (including path).
|
||||
*/
|
||||
QString desktopBackground(int screen=-1) const;
|
||||
|
||||
/// Returns the current lxqt theme.
|
||||
static const LXQtTheme ¤tTheme();
|
||||
|
||||
/// Returns the all themes found in the system.
|
||||
static QList<LXQtTheme> allThemes();
|
||||
|
||||
private:
|
||||
static LXQtTheme* mInstance;
|
||||
QSharedDataPointer<LXQtThemeData> d;
|
||||
};
|
||||
|
||||
/*!
|
||||
A global pointer referring to the unique LXQtTheme object.
|
||||
It is equivalent to the pointer returned by the LXQtTheme::instance() function.
|
||||
Only one theme object can be created. !*/
|
||||
|
||||
#define lxqtTheme LXQtTheme::currentTheme()
|
||||
|
||||
|
||||
class LXQT_API SettingsCache
|
||||
{
|
||||
public:
|
||||
explicit SettingsCache(QSettings &settings);
|
||||
explicit SettingsCache(QSettings *settings);
|
||||
virtual ~SettingsCache() {}
|
||||
|
||||
void loadFromSettings();
|
||||
void loadToSettings();
|
||||
|
||||
private:
|
||||
QSettings &mSettings;
|
||||
QHash<QString, QVariant> mCache;
|
||||
};
|
||||
|
||||
class GlobalSettingsPrivate;
|
||||
|
||||
class GlobalSettings: public Settings
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
GlobalSettings();
|
||||
~GlobalSettings();
|
||||
|
||||
signals:
|
||||
/// Signal emitted when the icon theme has changed.
|
||||
void iconThemeChanged();
|
||||
|
||||
/// Signal emitted when the lxqt theme has changed.
|
||||
void lxqtThemeChanged();
|
||||
|
||||
protected slots:
|
||||
void fileChanged();
|
||||
|
||||
private:
|
||||
GlobalSettingsPrivate* const d_ptr;
|
||||
Q_DECLARE_PRIVATE(GlobalSettings)
|
||||
};
|
||||
|
||||
} // namespace LXQt
|
||||
#endif // LXQTSETTINGS_H
|
@ -1,111 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://lxqt.org
|
||||
*
|
||||
* Copyright: 2014 LXQt team
|
||||
* Authors:
|
||||
* Luís Pereira <luis.artur.pereira@gmail.com>
|
||||
*
|
||||
* This program or library is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
#include "lxqtsingleapplication.h"
|
||||
#include "singleapplicationadaptor.h"
|
||||
#include <KWindowSystem/KWindowSystem>
|
||||
#include <KWindowSystem/NETWM>
|
||||
#include <QDBusMessage>
|
||||
#include <QWidget>
|
||||
#include <QDebug>
|
||||
#include <QTimer>
|
||||
|
||||
using namespace LXQt;
|
||||
|
||||
SingleApplication::SingleApplication(int &argc, char **argv, StartOptions options)
|
||||
: Application(argc, argv),
|
||||
mActivationWindow(0)
|
||||
{
|
||||
QString service =
|
||||
QString::fromLatin1("org.lxqt.%1").arg(QApplication::applicationName());
|
||||
|
||||
QDBusConnection bus = QDBusConnection::sessionBus();
|
||||
|
||||
if (!bus.isConnected()) {
|
||||
QLatin1String errorMessage("Can't connect to the D-Bus session bus\n"
|
||||
"Make sure the D-Bus daemon is running");
|
||||
|
||||
/* ExitOnDBusFailure is the default. Any value other than
|
||||
NoExitOnDBusFailure will be taken as ExitOnDBusFailure (the default).
|
||||
*/
|
||||
if (options == NoExitOnDBusFailure) {
|
||||
qDebug() << Q_FUNC_INFO << errorMessage;
|
||||
return;
|
||||
} else {
|
||||
qCritical() << Q_FUNC_INFO << errorMessage;
|
||||
QTimer::singleShot(0, [this] { exit(1); });
|
||||
}
|
||||
}
|
||||
|
||||
bool registered = (bus.registerService(service) ==
|
||||
QDBusConnectionInterface::ServiceRegistered);
|
||||
if (registered) { // We are the primary instance
|
||||
SingleApplicationAdaptor *mAdaptor = new SingleApplicationAdaptor(this);
|
||||
QLatin1String objectPath("/");
|
||||
bus.registerObject(objectPath, mAdaptor,
|
||||
QDBusConnection::ExportAllSlots);
|
||||
} else { // We are the second outstance
|
||||
QDBusMessage msg = QDBusMessage::createMethodCall(service,
|
||||
QStringLiteral("/"),
|
||||
QStringLiteral("org.lxqt.SingleApplication"),
|
||||
QStringLiteral("activateWindow"));
|
||||
QDBusConnection::sessionBus().send(msg);
|
||||
|
||||
QTimer::singleShot(0, [this] { exit(0); });
|
||||
}
|
||||
}
|
||||
|
||||
SingleApplication::~SingleApplication()
|
||||
{
|
||||
}
|
||||
|
||||
void SingleApplication::setActivationWindow(QWidget *w)
|
||||
{
|
||||
mActivationWindow = w;
|
||||
}
|
||||
|
||||
QWidget *SingleApplication::activationWindow() const
|
||||
{
|
||||
return mActivationWindow;
|
||||
}
|
||||
|
||||
void SingleApplication::activateWindow()
|
||||
{
|
||||
if (mActivationWindow) {
|
||||
mActivationWindow->show();
|
||||
WId window = mActivationWindow->effectiveWinId();
|
||||
|
||||
KWindowInfo info(window, NET::WMDesktop);
|
||||
int windowDesktop = info.desktop();
|
||||
|
||||
if (windowDesktop != KWindowSystem::currentDesktop())
|
||||
KWindowSystem::setCurrentDesktop(windowDesktop);
|
||||
KWindowSystem::activateWindow(window);
|
||||
} else {
|
||||
qDebug() << Q_FUNC_INFO << "activationWindow not set or null";
|
||||
}
|
||||
}
|
@ -1,158 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://lxqt.org
|
||||
*
|
||||
* Copyright: 2014 LXQt team
|
||||
* Authors:
|
||||
* Luís Pereira <luis.artur.pereira@gmail.com>
|
||||
*
|
||||
* This program or library is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
#ifndef LXQTSINGLEAPPLICATION_H
|
||||
#define LXQTSINGLEAPPLICATION_H
|
||||
|
||||
#include "lxqtapplication.h"
|
||||
|
||||
class QWidget;
|
||||
|
||||
namespace LXQt {
|
||||
|
||||
/*! \class SingleApplication
|
||||
* \brief The SingleApplication class provides an single instance Application.
|
||||
*
|
||||
* This class allows the user to create applications where only one instance
|
||||
* is allowed to be running at an given time. If the user tries to launch
|
||||
* another instance, the already running instance will be activated instead.
|
||||
*
|
||||
* The user has to set the activation window with setActivationWindow. If it
|
||||
* doesn't the second instance will quietly exit without activating the first
|
||||
* instance window. In any case only one instance is allowed.
|
||||
*
|
||||
* These classes depend on D-Bus and KF5::WindowSystem
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* // Original code
|
||||
* int main(int argc, char **argv)
|
||||
* {
|
||||
* LXQt::Application app(argc, argv);
|
||||
*
|
||||
* MainWidget w;
|
||||
* w.show();
|
||||
*
|
||||
* return app.exec();
|
||||
* }
|
||||
*
|
||||
* // Using the library
|
||||
* int main(int argc, char **argv)
|
||||
* {
|
||||
* LXQt::SingleApplication app(argc, argv);
|
||||
*
|
||||
* MainWidget w;
|
||||
* app.setActivationWindow(&w);
|
||||
* w.show();
|
||||
*
|
||||
* return app.exec();
|
||||
* }
|
||||
* \endcode
|
||||
* \sa SingleApplication
|
||||
*/
|
||||
|
||||
class LXQT_API SingleApplication : public Application {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \brief Options to control the D-Bus failure related application behaviour
|
||||
*
|
||||
* By default (ExitOnDBusFailure) if an instance can't connect to the D-Bus
|
||||
* session bus, that instance calls ::exit(1). Not even the first instance
|
||||
* will run. Connecting to the D-Bus session bus is an condition to
|
||||
* guarantee that only one instance will run.
|
||||
*
|
||||
* If an user wants to allow an application to run without D-Bus, it must
|
||||
* use the NoExitOnDBusFailure option.
|
||||
*
|
||||
* ExitOnDBusFailure is the default.
|
||||
*/
|
||||
enum StartOptions {
|
||||
/** Exit if the connection to the D-Bus session bus fails.
|
||||
* It's the default
|
||||
*/
|
||||
ExitOnDBusFailure,
|
||||
/** Don't exit if the connection to the D-Bus session bus fails.*/
|
||||
NoExitOnDBusFailure
|
||||
};
|
||||
Q_ENUM(StartOptions)
|
||||
|
||||
/*!
|
||||
* \brief Construct a LXQt SingleApplication object.
|
||||
* \param argc standard argc as in QApplication
|
||||
* \param argv standard argv as in QApplication
|
||||
* \param options Control the on D-Bus failure application behaviour
|
||||
*
|
||||
* \sa StartOptions.
|
||||
*/
|
||||
SingleApplication(int &argc, char **argv, StartOptions options = ExitOnDBusFailure);
|
||||
virtual ~SingleApplication();
|
||||
|
||||
/*!
|
||||
* \brief Sets the activation window.
|
||||
* \param w activation window.
|
||||
*
|
||||
* Sets the activation window of this application to w. The activation
|
||||
* window is the widget that will be activated by \a activateWindow().
|
||||
*
|
||||
* \sa activationWindow() \sa activateWindow();
|
||||
*/
|
||||
void setActivationWindow(QWidget *w);
|
||||
|
||||
/*!
|
||||
* \brief Gets the current activation window.
|
||||
* \return The current activation window.
|
||||
*
|
||||
* \sa setActivationWindow();
|
||||
*/
|
||||
QWidget *activationWindow() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
/*!
|
||||
* \brief Activates this application activation window.
|
||||
*
|
||||
* Changes to the desktop where this applications is. It then de-minimizes,
|
||||
* raises and activates the application's activation window.
|
||||
* If no activation window has been set, this function does nothing.
|
||||
*
|
||||
* \sa setActivationWindow();
|
||||
*/
|
||||
void activateWindow();
|
||||
|
||||
private:
|
||||
QWidget *mActivationWindow;
|
||||
};
|
||||
|
||||
#if defined(lxqtSingleApp)
|
||||
#undef lxqtSingleApp
|
||||
#endif
|
||||
#define lxqtSingleApp (static_cast<LXQt::SingleApplication *>(qApp))
|
||||
|
||||
} // namespace LXQt
|
||||
|
||||
#endif // LXQTSINGLEAPPLICATION_H
|
@ -1,186 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright: 2013 LXQt team
|
||||
* Authors:
|
||||
* Alexander Sokoloff <sokoloff.a@gmail.com>
|
||||
Luís Pereira <luis.artur.pereira@gmail.com>
|
||||
*
|
||||
* This program or library is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
#include "lxqttranslator.h"
|
||||
#include <QTranslator>
|
||||
#include <QLocale>
|
||||
#include <QDebug>
|
||||
#include <QCoreApplication>
|
||||
#include <QLibraryInfo>
|
||||
#include <QStringList>
|
||||
#include <QStringBuilder>
|
||||
#include <QFileInfo>
|
||||
|
||||
#include <XdgDirs>
|
||||
|
||||
using namespace LXQt;
|
||||
|
||||
bool translate(const QString &name, const QString &owner = QString());
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
QStringList *getSearchPaths()
|
||||
{
|
||||
static QStringList *searchPath = 0;
|
||||
|
||||
if (searchPath == 0)
|
||||
{
|
||||
searchPath = new QStringList();
|
||||
*searchPath << XdgDirs::dataDirs(QLatin1Char('/') % LXQT_RELATIVE_SHARE_TRANSLATIONS_DIR);
|
||||
*searchPath << QString(LXQT_SHARE_TRANSLATIONS_DIR);
|
||||
searchPath->removeDuplicates();
|
||||
}
|
||||
|
||||
return searchPath;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
QStringList LXQt::Translator::translationSearchPaths()
|
||||
{
|
||||
return *(getSearchPaths());
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
void Translator::setTranslationSearchPaths(const QStringList &paths)
|
||||
{
|
||||
QStringList *p = getSearchPaths();
|
||||
p->clear();
|
||||
*p << paths;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
bool translate(const QString &name, const QString &owner)
|
||||
{
|
||||
const QString locale = QLocale::system().name();
|
||||
QTranslator *appTranslator = new QTranslator(qApp);
|
||||
|
||||
QStringList *paths = getSearchPaths();
|
||||
foreach(const QString &path, *paths)
|
||||
{
|
||||
QStringList subPaths;
|
||||
|
||||
if (!owner.isEmpty())
|
||||
{
|
||||
subPaths << path % QChar('/') % owner % QChar('/') % name;
|
||||
}
|
||||
else
|
||||
{
|
||||
subPaths << path % QChar('/') % name;
|
||||
subPaths << path;
|
||||
}
|
||||
|
||||
foreach(const QString &p, subPaths)
|
||||
{
|
||||
if (appTranslator->load(name + "_" + locale, p))
|
||||
{
|
||||
QCoreApplication::installTranslator(appTranslator);
|
||||
return true;
|
||||
}
|
||||
else if (locale == QLatin1String("C") ||
|
||||
locale.startsWith(QLatin1String("en")))
|
||||
{
|
||||
// English is the default. Even if there isn't an translation
|
||||
// file, we return true. It's translated anyway.
|
||||
delete appTranslator;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we got here, no translation was loaded. appTranslator has no use.
|
||||
delete appTranslator;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
bool Translator::translateApplication(const QString &applicationName)
|
||||
{
|
||||
const QString locale = QLocale::system().name();
|
||||
QTranslator *qtTranslator = new QTranslator(qApp);
|
||||
|
||||
if (qtTranslator->load("qt_" + locale, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
|
||||
{
|
||||
qApp->installTranslator(qtTranslator);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete qtTranslator;
|
||||
}
|
||||
|
||||
if (!applicationName.isEmpty())
|
||||
return translate(applicationName);
|
||||
else
|
||||
return translate(QFileInfo(QCoreApplication::applicationFilePath()).baseName());
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
|
||||
************************************************/
|
||||
bool Translator::translateLibrary(const QString &libraryName)
|
||||
{
|
||||
static QSet<QString> loadedLibs;
|
||||
|
||||
if (loadedLibs.contains(libraryName))
|
||||
return true;
|
||||
|
||||
loadedLibs.insert(libraryName);
|
||||
|
||||
return translate(libraryName);
|
||||
}
|
||||
|
||||
bool Translator::translatePlugin(const QString &pluginName, const QString& type)
|
||||
{
|
||||
static QSet<QString> loadedPlugins;
|
||||
|
||||
const QString fullName = type % QChar('/') % pluginName;
|
||||
if (loadedPlugins.contains(fullName))
|
||||
return true;
|
||||
|
||||
loadedPlugins.insert(pluginName);
|
||||
return translate(pluginName, type);
|
||||
}
|
||||
|
||||
static void loadSelfTranslation()
|
||||
{
|
||||
Translator::translateLibrary(QLatin1String("liblxqt"));
|
||||
}
|
||||
|
||||
Q_COREAPP_STARTUP_FUNCTION(loadSelfTranslation)
|
@ -1,72 +0,0 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://razor-qt.org
|
||||
*
|
||||
* Copyright: 2013 LXQt team
|
||||
* Authors:
|
||||
* Alexander Sokoloff <sokoloff.a@gmail.com>
|
||||
Luís Pereira <luis.artur.pereira@gmail.com>
|
||||
*
|
||||
* This program or library is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
* END_COMMON_COPYRIGHT_HEADER */
|
||||
|
||||
#ifndef LXQTTRANSLATOR_H
|
||||
#define LXQTTRANSLATOR_H
|
||||
|
||||
#include <QStringList>
|
||||
#include "lxqtglobals.h"
|
||||
|
||||
namespace LXQt
|
||||
{
|
||||
/**
|
||||
The Translator class provides internationalization support for application and librarioes.
|
||||
**/
|
||||
class LXQT_API Translator
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Returns a list of paths that the application will search translations files.
|
||||
**/
|
||||
static QStringList translationSearchPaths();
|
||||
|
||||
/**
|
||||
Sets the list of directories to search translations. All existing paths
|
||||
will be deleted and the path list will consist of the paths given in paths.
|
||||
**/
|
||||
static void setTranslationSearchPaths(const QStringList &paths);
|
||||
|
||||
/**
|
||||
Loads translations for application. If applicationName is not specified,
|
||||
then basename of QCoreApplication::applicationFilePath() is used.
|
||||
Returns true if the translation is successfully loaded; otherwise returns false.
|
||||
**/
|
||||
static bool translateApplication(const QString &applicationName = QString());
|
||||
|
||||
/**
|
||||
Loads translations for application. If applicationName is not specified,
|
||||
then basename of QCoreApplication::applicationFilePath() is used.
|
||||
Returns true if the translation is successfully loaded; otherwise returns false.
|
||||
**/
|
||||
static bool translateLibrary(const QString &libraryName = QString());
|
||||
|
||||
static bool translatePlugin(const QString &pluginName, const QString& type);
|
||||
};
|
||||
|
||||
} // namespace LXQt
|
||||
#endif // LXQTTRANSLATOR_H
|
Loading…
Reference in new issue