Compare commits
7 Commits
ubuntu/que
...
upstream/0
Author | SHA1 | Date | |
---|---|---|---|
|
5693f76b61 | ||
|
6168001088 | ||
|
ad738c24f8 | ||
|
8594ea0414 | ||
|
b34de2c23b | ||
|
4ca5973d60 | ||
|
88b1696810 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +0,0 @@
|
||||
build
|
||||
*.kdev4
|
6
AUTHORS
6
AUTHORS
@ -3,9 +3,7 @@ Upstream Authors:
|
||||
Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
||||
|
||||
Copyright:
|
||||
Copyright (c) 2013-2014 LXQt team
|
||||
Copyright (c) 2013-2017 LXQt team
|
||||
|
||||
License: GPL-2 and LGPL-2.1+
|
||||
License: LGPL-2.1+
|
||||
The full text of the licenses can be found in the 'COPYING' file.
|
||||
|
||||
Based on source code from the Qt 4.8 Project by Digia Plc
|
||||
|
109
CHANGELOG
Normal file
109
CHANGELOG
Normal file
@ -0,0 +1,109 @@
|
||||
|
||||
lxqt-qtplugin-0.12.0 / 2017-10-21
|
||||
=================================
|
||||
|
||||
* Set an informal patch version
|
||||
* Don't export github templates
|
||||
* Flag unused vars in onServiceOwnerChanged
|
||||
* Fix missing variable declaration
|
||||
* Handle QML (as @PCMan suggested)
|
||||
* Use mime functions added by @PCMan
|
||||
* Loading and saving window/splitter size
|
||||
* Central positioning with respect to parent
|
||||
* Set window title correctly
|
||||
* Qt version conditions
|
||||
* Just made it compilable
|
||||
* Handle mime-type filters for file dialog. Set custom file dialog labels.
|
||||
* Update options properly.
|
||||
* Implement a basic file dialog helper using libfm-qt's Fm::FileDialog.
|
||||
* Avoid using Qt-specific keywords such as signal/slot and foreach. Instead, use macros.
|
||||
* LXQtPlatformTheme: Make Qt use default palette (#22)
|
||||
* LXQtPlatformTheme: Add icon FollowColorScheme config (#21)
|
||||
* Prevent a possible C++11 range for detach (#20)
|
||||
* Use the CMake MODULE library type.
|
||||
* LXQtPlatformTheme: Propagate wheelScrollLines
|
||||
* LXQtPlatformTheme: Do not provide own palette
|
||||
* Fix multiple StatusNotifierItems.
|
||||
* Bump year
|
||||
* Updates lxqt-build-tools required version
|
||||
|
||||
0.11.1 / 2016-12-11
|
||||
===================
|
||||
|
||||
* Release 0.11.1: Update changelog
|
||||
* Use lxqt-build-tools
|
||||
* Use the new lxqt-build-tools package
|
||||
* Remove cpack (#14)
|
||||
|
||||
0.11.0 / 2016-09-24
|
||||
===================
|
||||
|
||||
* Release 0.11.0: Add changelog
|
||||
* Add Qt5XdgIconLoader as dependency (#13)
|
||||
* Update README.md
|
||||
* statusnotifieritem: Correctly handle menu
|
||||
* Cleaned up licenses
|
||||
* Use XdgIconLoader library (#10)
|
||||
* xdgIconThemePaths: Use QString::SkipEmptyParts
|
||||
* xdgIconThemePaths: Remove duplicated paths
|
||||
* Adds $XDG_DATA_HOME to the XdgIconThemePaths
|
||||
* Bump year in AUTHORS
|
||||
|
||||
0.10.0 / 2015-11-02
|
||||
===================
|
||||
|
||||
* Remove unnecessary qDebug calls
|
||||
* Use markdown for README
|
||||
* Fix license file
|
||||
* Fix mixed indents
|
||||
* Remove Qt >= 5.3 check
|
||||
* Removed GPL2, added Digia Qt LGPL Exception version 1.1
|
||||
* SNI: don't create a SNI if support isn't available
|
||||
* SNI: monitor the watcher in case the host restarts
|
||||
* SNI: implement scroll, showMessage and improve icons
|
||||
* SNI: create default context menu
|
||||
* Support the StatusNotifierItem spec natively
|
||||
* Use the standard palette of the current Qt theme
|
||||
* Handles CMake policy CMP0063
|
||||
* Use the LXQtCompilerSettings CMake module
|
||||
* Add .gitignore
|
||||
* Updates the build system to use the Targets infrastructure
|
||||
* Remove trailing whitespaces
|
||||
* removed debug (which makes every app too verbose)
|
||||
|
||||
0.9.0 / 2015-01-19
|
||||
==================
|
||||
|
||||
* Try to workaround bug #441 - All LXQt::Settings and QSettings file change monitoring stop working.
|
||||
* - Unify naming for a unique lxqt. No more suffixes
|
||||
* Qt5: Use XDG_DATA_DIR for themeHint::IconThemeSearchPaths
|
||||
* CMakeLists.txt cleanuop and drop Qt4 support
|
||||
|
||||
0.8.0 / 2014-07-18
|
||||
==================
|
||||
|
||||
* Apply the default application font on program startup.
|
||||
* Apply the new font to all apps correctly and fix lxde/lxde-qt bug #212 - Changing font or theme in lxqt-config-appearance has no effect.
|
||||
* Make the code compile with Qt 5.2, fix lxde-qt bug #207.
|
||||
* Fix lxde-qt bug #207: lxqt-qtplugin fail to build with Qt5.
|
||||
* Use qmake to query the path of Qt5 plugin dir, which is much more reliable.
|
||||
* Update README and provide information for usage and debugging.
|
||||
* Use a more reliable and portable way to get the path of Qt5 plugin dir.
|
||||
* Support setting default UI font.
|
||||
* Make "oxygen" the default icon theme name. * Apply new style name and icon theme name when the config file is changed.
|
||||
* Simplify the Qt5 plugin and remove liblxqt dependency from it.
|
||||
* Correctly read config values.
|
||||
* Try to load some Qt settings.
|
||||
* Implement a very basic Qt5 platform theme plugin.
|
||||
* Prepare for Qt5 support.
|
||||
* Use preferred header style.
|
||||
* Remove unnecessary debug messages.
|
||||
* Fix int-to-enum casting
|
||||
|
||||
0.7.0 / 2014-04-29
|
||||
==================
|
||||
|
||||
* Update AUTHORS and COPYING
|
||||
* Add CPack rules for creating tarball
|
||||
* Support toolbar styles and activating items with single click.
|
||||
* Initial import.
|
@ -1,25 +1,31 @@
|
||||
cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)
|
||||
project(lxqt-qtplugin)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
set(LXQTBT_MINIMUM_VERSION "0.4.0")
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
|
||||
find_package(Qt5Widgets REQUIRED QUIET)
|
||||
find_package(Qt5LinguistTools REQUIRED QUIET)
|
||||
find_package(Qt5Widgets REQUIRED)
|
||||
find_package(Qt5LinguistTools REQUIRED)
|
||||
find_package(Qt5DBus REQUIRED)
|
||||
find_package(dbusmenu-qt5 REQUIRED)
|
||||
find_package(lxqt-build-tools ${LXQTBT_MINIMUM_VERSION} REQUIRED)
|
||||
find_package(Qt5XdgIconLoader REQUIRED)
|
||||
|
||||
find_package(lxqt REQUIRED QUIET)
|
||||
# Patch Version 0
|
||||
|
||||
# for file dialog support
|
||||
find_package(Qt5X11Extras REQUIRED)
|
||||
find_package(fm-qt REQUIRED)
|
||||
|
||||
include(LXQtCompilerSettings NO_POLICY_SCOPE)
|
||||
|
||||
add_subdirectory(src)
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif()
|
||||
|
||||
# building tarball with CPack -------------------------------------------------
|
||||
include(InstallRequiredSystemLibraries)
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR ${LXQT_MAJOR_VERSION})
|
||||
set(CPACK_PACKAGE_VERSION_MINOR ${LXQT_MINOR_VERSION})
|
||||
set(CPACK_PACKAGE_VERSION_PATCH ${LXQT_PATCH_VERSION})
|
||||
set(CPACK_GENERATOR TBZ2)
|
||||
set(CPACK_SOURCE_GENERATOR TBZ2)
|
||||
set(CPACK_SOURCE_IGNORE_FILES /build/;.gitignore;.*~;.git;.kdev4;temp)
|
||||
include(CPack)
|
||||
add_subdirectory(src)
|
||||
|
@ -1,9 +1,8 @@
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
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.
|
||||
|
||||
@ -23,8 +22,7 @@ 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.
|
||||
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
|
||||
@ -89,9 +87,9 @@ 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
|
||||
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.
|
||||
@ -138,8 +136,8 @@ 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.
|
||||
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
|
||||
@ -305,10 +303,10 @@ of these things:
|
||||
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.
|
||||
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
|
||||
@ -386,10 +384,9 @@ 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.
|
||||
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
|
||||
@ -407,11 +404,11 @@ 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.
|
||||
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.
|
12
README
12
README
@ -1,12 +0,0 @@
|
||||
libqtlxqt - LXQt system integration plugin for Qt.
|
||||
|
||||
With this plugin, all Qt-based programs can adopt settings of
|
||||
LXQt, such as the icon theme.
|
||||
|
||||
To use the plugin in Qt 5, we have to export the environment
|
||||
variable QT_QPA_PLATFORMTHEME=lxqt. Then every Qt5 program
|
||||
can load the theme plugin.
|
||||
If, for some unknown reasons, the plugin is not loaded, we can
|
||||
debug the plugin by exporting QT_DEBUG_PLUGINS=1.
|
||||
Then, Qt5 will print detailed information and error messages
|
||||
about all plugins in the console when running any Qt5 programs.
|
27
README.md
Normal file
27
README.md
Normal file
@ -0,0 +1,27 @@
|
||||
# lxqt-qtplugin
|
||||
|
||||
## Overview
|
||||
|
||||
This repository is providing a library `libqtlxqt` to integrate Qt with LXQt.
|
||||
|
||||
With this plugin, all Qt-based programs can adopt settings of LXQt, such as the icon theme.
|
||||
|
||||
## Installation
|
||||
|
||||
### Compiling source code
|
||||
|
||||
Runtime dependencies are libdbusmenu-qt5 and [liblxqt](https://github.com/lxde/liblxqt).
|
||||
Additional build dependencies are CMake and qttools, optionally Git to pull latest VCS checkouts.
|
||||
|
||||
Code configuration is handled by CMake. CMake variable `CMAKE_INSTALL_PREFIX` has to be set to `/usr` on most operating systems.
|
||||
|
||||
To build run `make`, to install `make install` which accepts variable `DESTDIR` as usual.
|
||||
|
||||
### Binary packages
|
||||
|
||||
Official binary packages are provided by all major Linux distributions like Arch Linux, Debian (as of Debian stretch only), Fedora and openSUSE. Just use your package manager to search for string `lxqt-qtplugin`.
|
||||
|
||||
## Configuration, Usage
|
||||
|
||||
To use the plugin in Qt 5, we have to export environment variable `QT_QPA_PLATFORMTHEME=lxqt`. Then every Qt5 program can load the theme plugin.
|
||||
If, for some unknown reasons, the plugin is not loaded, we can debug the plugin by exporting `QT_DEBUG_PLUGINS=1`. Then, Qt5 will print detailed information and error messages about all plugins in the console when running any Qt5 programs.
|
@ -3,17 +3,40 @@ include_directories(
|
||||
"${CMAKE_CURRENT_BINARY_DIR}"
|
||||
)
|
||||
|
||||
set(qtlxqt_HDRS
|
||||
lxqtplatformtheme.h
|
||||
lxqtsystemtrayicon.h
|
||||
lxqtfiledialoghelper.h
|
||||
statusnotifieritem/statusnotifieritem.h
|
||||
statusnotifieritem/dbustypes.h
|
||||
)
|
||||
|
||||
set(qtlxqt_SRCS
|
||||
main.cpp
|
||||
lxqtplatformtheme.cpp
|
||||
lxqtsystemtrayicon.cpp
|
||||
lxqtfiledialoghelper.cpp
|
||||
statusnotifieritem/statusnotifieritem.cpp
|
||||
statusnotifieritem/dbustypes.cpp
|
||||
)
|
||||
|
||||
add_library(qtlxqt SHARED ${qtlxqt_SRCS})
|
||||
qt5_add_dbus_adaptor(qtlxqt_SRCS
|
||||
statusnotifieritem/org.kde.StatusNotifierItem.xml
|
||||
statusnotifieritem/statusnotifieritem.h
|
||||
StatusNotifierItem
|
||||
)
|
||||
|
||||
add_library(qtlxqt MODULE ${qtlxqt_HDRS} ${qtlxqt_SRCS})
|
||||
|
||||
target_link_libraries(qtlxqt
|
||||
Qt5::Widgets
|
||||
Qt5::DBus
|
||||
dbusmenu-qt5
|
||||
Qt5XdgIconLoader
|
||||
fm-qt
|
||||
)
|
||||
|
||||
|
||||
# there is no standard way to get the plugin dir of Qt5 with cmake
|
||||
# The best way is get_target_property(QT_PLUGINS_DIR Qt5::QGtk2ThemePlugin LOCATION).
|
||||
# This directly returns the platformthemes dir. However, this does not work
|
||||
|
224
src/lxqtfiledialoghelper.cpp
Normal file
224
src/lxqtfiledialoghelper.cpp
Normal file
@ -0,0 +1,224 @@
|
||||
#include "lxqtfiledialoghelper.h"
|
||||
|
||||
#include <libfm-qt/libfmqt.h>
|
||||
#include <libfm-qt/filedialog.h>
|
||||
|
||||
#include <QWindow>
|
||||
#include <QDebug>
|
||||
#include <QTimer>
|
||||
#include <QSettings>
|
||||
|
||||
#include <memory>
|
||||
|
||||
static std::unique_ptr<Fm::LibFmQt> libfmQtContext_;
|
||||
|
||||
LXQtFileDialogHelper::LXQtFileDialogHelper() {
|
||||
if(!libfmQtContext_) {
|
||||
// initialize libfm-qt only once
|
||||
libfmQtContext_ = std::unique_ptr<Fm::LibFmQt>{new Fm::LibFmQt()};
|
||||
}
|
||||
|
||||
// can only be used after libfm-qt initialization
|
||||
dlg_ = std::unique_ptr<Fm::FileDialog>(new Fm::FileDialog());
|
||||
connect(dlg_.get(), &Fm::FileDialog::accepted, [this]() {
|
||||
saveSettings();
|
||||
accept();
|
||||
});
|
||||
connect(dlg_.get(), &Fm::FileDialog::rejected, [this]() {
|
||||
saveSettings();
|
||||
reject();
|
||||
});
|
||||
|
||||
connect(dlg_.get(), &Fm::FileDialog::fileSelected, this, &LXQtFileDialogHelper::fileSelected);
|
||||
connect(dlg_.get(), &Fm::FileDialog::filesSelected, this, &LXQtFileDialogHelper::filesSelected);
|
||||
connect(dlg_.get(), &Fm::FileDialog::currentChanged, this, &LXQtFileDialogHelper::currentChanged);
|
||||
connect(dlg_.get(), &Fm::FileDialog::directoryEntered, this, &LXQtFileDialogHelper::directoryEntered);
|
||||
connect(dlg_.get(), &Fm::FileDialog::filterSelected, this, &LXQtFileDialogHelper::filterSelected);
|
||||
}
|
||||
|
||||
LXQtFileDialogHelper::~LXQtFileDialogHelper() {
|
||||
}
|
||||
|
||||
void LXQtFileDialogHelper::exec() {
|
||||
dlg_->exec();
|
||||
}
|
||||
|
||||
bool LXQtFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow* parent) {
|
||||
dlg_->setAttribute(Qt::WA_NativeWindow, true); // without this, sometimes windowHandle() will return nullptr
|
||||
|
||||
dlg_->setWindowFlags(windowFlags);
|
||||
dlg_->setWindowModality(windowModality);
|
||||
|
||||
// Reference: KDE implementation
|
||||
// https://github.com/KDE/plasma-integration/blob/master/src/platformtheme/kdeplatformfiledialoghelper.cpp
|
||||
dlg_->windowHandle()->setTransientParent(parent);
|
||||
|
||||
loadSettings();
|
||||
// central positioning with respect to the parent window
|
||||
if(parent && parent->isVisible()) {
|
||||
dlg_->move(parent->x() + (parent->width() - dlg_->width()) / 2,
|
||||
parent->y() + (parent->height() - dlg_->height()) / 2);
|
||||
}
|
||||
|
||||
applyOptions();
|
||||
|
||||
// NOTE: the timer here is required as a workaround borrowed from KDE. Without this, the dialog UI will be blocked.
|
||||
// QFileDialog calls our platform plugin to show our own native file dialog instead of showing its widget.
|
||||
// However, it still creates a hidden dialog internally, and then make it modal.
|
||||
// So user input from all other windows that are not the children of the QFileDialog widget will be blocked.
|
||||
// This includes our own dialog. After the return of this show() method, QFileDialog creates its own window and
|
||||
// then make it modal, which blocks our UI. The timer schedule a delayed popup of our file dialog, so we can
|
||||
// show again after QFileDialog and override the modal state. Then our UI can be unblocked.
|
||||
QTimer::singleShot(0, dlg_.get(), &QDialog::show);
|
||||
dlg_->setFocus();
|
||||
return true;
|
||||
}
|
||||
|
||||
void LXQtFileDialogHelper::hide() {
|
||||
dlg_->hide();
|
||||
}
|
||||
|
||||
bool LXQtFileDialogHelper::defaultNameFilterDisables() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void LXQtFileDialogHelper::setDirectory(const QUrl& directory) {
|
||||
dlg_->setDirectory(directory);
|
||||
}
|
||||
|
||||
QUrl LXQtFileDialogHelper::directory() const {
|
||||
return dlg_->directory();
|
||||
}
|
||||
|
||||
void LXQtFileDialogHelper::selectFile(const QUrl& filename) {
|
||||
dlg_->selectFile(filename);
|
||||
}
|
||||
|
||||
QList<QUrl> LXQtFileDialogHelper::selectedFiles() const {
|
||||
return dlg_->selectedFiles();
|
||||
}
|
||||
|
||||
void LXQtFileDialogHelper::setFilter() {
|
||||
// FIXME: what's this?
|
||||
// The gtk+ 3 file dialog helper in Qt5 update options in this method.
|
||||
applyOptions();
|
||||
}
|
||||
|
||||
void LXQtFileDialogHelper::selectNameFilter(const QString& filter) {
|
||||
dlg_->selectNameFilter(filter);
|
||||
}
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
|
||||
QString LXQtFileDialogHelper::selectedMimeTypeFilter() const {
|
||||
return dlg_->selectedMimeTypeFilter();
|
||||
}
|
||||
|
||||
void LXQtFileDialogHelper::selectMimeTypeFilter(const QString& filter) {
|
||||
dlg_->selectMimeTypeFilter(filter);
|
||||
}
|
||||
#endif
|
||||
|
||||
QString LXQtFileDialogHelper::selectedNameFilter() const {
|
||||
return dlg_->selectedNameFilter();
|
||||
}
|
||||
|
||||
bool LXQtFileDialogHelper::isSupportedUrl(const QUrl& url) const {
|
||||
return dlg_->isSupportedUrl(url);
|
||||
}
|
||||
|
||||
void LXQtFileDialogHelper::applyOptions() {
|
||||
auto& opt = options();
|
||||
|
||||
// set title
|
||||
if(opt->windowTitle().isEmpty()) {
|
||||
dlg_->setWindowTitle(opt->acceptMode() == QFileDialogOptions::AcceptOpen ? tr("Open File")
|
||||
: tr("Save File"));
|
||||
}
|
||||
else {
|
||||
dlg_->setWindowTitle(opt->windowTitle());
|
||||
}
|
||||
|
||||
dlg_->setFilter(opt->filter());
|
||||
dlg_->setViewMode(opt->viewMode() == QFileDialogOptions::Detail ? Fm::FolderView::DetailedListMode
|
||||
: Fm::FolderView::CompactMode);
|
||||
dlg_->setFileMode(QFileDialog::FileMode(opt->fileMode()));
|
||||
dlg_->setAcceptMode(QFileDialog::AcceptMode(opt->acceptMode())); // also sets a default label for accept button
|
||||
// bool useDefaultNameFilters() const;
|
||||
dlg_->setNameFilters(opt->nameFilters());
|
||||
if(!opt->mimeTypeFilters().empty()) {
|
||||
dlg_->setMimeTypeFilters(opt->mimeTypeFilters());
|
||||
}
|
||||
|
||||
dlg_->setDefaultSuffix(opt->defaultSuffix());
|
||||
// QStringList history() const;
|
||||
|
||||
// explicitly set labels
|
||||
for(int i = 0; i < QFileDialogOptions::DialogLabelCount; ++i) {
|
||||
auto label = static_cast<QFileDialogOptions::DialogLabel>(i);
|
||||
if(opt->isLabelExplicitlySet(label)) {
|
||||
dlg_->setLabelText(static_cast<QFileDialog::DialogLabel>(label), opt->labelText(label));
|
||||
}
|
||||
}
|
||||
|
||||
auto url = opt->initialDirectory();
|
||||
if(url.isValid()) {
|
||||
dlg_->setDirectory(url);
|
||||
}
|
||||
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
|
||||
auto filter = opt->initiallySelectedMimeTypeFilter();
|
||||
if(!filter.isEmpty()) {
|
||||
selectMimeTypeFilter(filter);
|
||||
}
|
||||
else {
|
||||
filter = opt->initiallySelectedNameFilter();
|
||||
if(!filter.isEmpty()) {
|
||||
selectNameFilter(opt->initiallySelectedNameFilter());
|
||||
}
|
||||
}
|
||||
#else
|
||||
auto filter = opt->initiallySelectedNameFilter();
|
||||
if(!filter.isEmpty()) {
|
||||
selectNameFilter(filter);
|
||||
}
|
||||
#endif
|
||||
|
||||
auto selectedFiles = opt->initiallySelectedFiles();
|
||||
for(const auto& selectedFile: selectedFiles) {
|
||||
selectFile(selectedFile);
|
||||
}
|
||||
// QStringList supportedSchemes() const;
|
||||
}
|
||||
|
||||
void LXQtFileDialogHelper::loadSettings() {
|
||||
QSettings settings(QSettings::UserScope, "lxqt", "filedialog");
|
||||
settings.beginGroup ("Sizes");
|
||||
dlg_->resize(settings.value("WindowSize", QSize(700, 500)).toSize());
|
||||
dlg_->setSplitterPos(settings.value("SplitterPos", 200).toInt());
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
void LXQtFileDialogHelper::saveSettings() {
|
||||
QSettings settings(QSettings::UserScope, "lxqt", "filedialog");
|
||||
settings.beginGroup ("Sizes");
|
||||
QSize windowSize = dlg_->size();
|
||||
if(settings.value("WindowSize") != windowSize) { // no redundant write
|
||||
settings.setValue("WindowSize", windowSize);
|
||||
}
|
||||
int splitterPos = dlg_->splitterPos();
|
||||
if(settings.value("SplitterPos") != splitterPos) {
|
||||
settings.setValue("SplitterPos", splitterPos);
|
||||
}
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
/*
|
||||
FileDialogPlugin::FileDialogPlugin() {
|
||||
|
||||
}
|
||||
|
||||
QPlatformFileDialogHelper *FileDialogPlugin::createHelper() {
|
||||
return new LXQtFileDialogHelper();
|
||||
}
|
||||
*/
|
50
src/lxqtfiledialoghelper.h
Normal file
50
src/lxqtfiledialoghelper.h
Normal file
@ -0,0 +1,50 @@
|
||||
#ifndef LXQTFILEDIALOGHELPER_H
|
||||
#define LXQTFILEDIALOGHELPER_H
|
||||
|
||||
#include <qpa/qplatformdialoghelper.h> // this private header is subject to changes
|
||||
#include <memory>
|
||||
|
||||
namespace Fm {
|
||||
class FileDialog;
|
||||
}
|
||||
|
||||
class Q_GUI_EXPORT LXQtFileDialogHelper : public QPlatformFileDialogHelper {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LXQtFileDialogHelper();
|
||||
|
||||
virtual ~LXQtFileDialogHelper();
|
||||
|
||||
// QPlatformDialogHelper
|
||||
void exec() override;
|
||||
bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) override;
|
||||
void hide() override;
|
||||
|
||||
// QPlatformFileDialogHelper
|
||||
bool defaultNameFilterDisables() const override;
|
||||
void setDirectory(const QUrl &directory) override;
|
||||
QUrl directory() const override;
|
||||
void selectFile(const QUrl &filename) override;
|
||||
QList<QUrl> selectedFiles() const override;
|
||||
void setFilter() override;
|
||||
void selectNameFilter(const QString &filter) override;
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
|
||||
QString selectedMimeTypeFilter() const override;
|
||||
void selectMimeTypeFilter(const QString &filter) override;
|
||||
#endif
|
||||
QString selectedNameFilter() const override;
|
||||
|
||||
bool isSupportedUrl(const QUrl &url) const override;
|
||||
|
||||
private:
|
||||
void applyOptions();
|
||||
void loadSettings();
|
||||
void saveSettings();
|
||||
|
||||
private:
|
||||
std::unique_ptr<Fm::FileDialog> dlg_;
|
||||
};
|
||||
|
||||
|
||||
#endif // LXQTFILEDIALOGHELPER_H
|
@ -44,12 +44,14 @@
|
||||
#include <QFileInfo>
|
||||
#include <QFileSystemWatcher>
|
||||
#include <QStyle>
|
||||
#include "qiconloader_p.h"
|
||||
#include <private/xdgiconloader/xdgiconloader_p.h>
|
||||
|
||||
#include "lxqtfiledialoghelper.h"
|
||||
|
||||
LXQtPlatformTheme::LXQtPlatformTheme():
|
||||
settingsWatcher_(NULL)
|
||||
iconFollowColorScheme_(true)
|
||||
, settingsWatcher_(NULL)
|
||||
{
|
||||
// qDebug() << "LXQT Platform Theme loaded";
|
||||
// When the plugin is loaded, it seems that the app is not yet running and
|
||||
// QThread environment is not completely set up. So creating filesystem watcher
|
||||
// does not work since it uses QSocketNotifier internally which can only be
|
||||
@ -81,6 +83,7 @@ void LXQtPlatformTheme::loadSettings() {
|
||||
|
||||
// icon theme
|
||||
iconTheme_ = settings.value("icon_theme", "oxygen").toString();
|
||||
iconFollowColorScheme_ = settings.value("icon_follow_color_scheme", iconFollowColorScheme_).toBool();
|
||||
|
||||
// read other widget related settings form LxQt settings.
|
||||
QByteArray tb_style = settings.value("tool_button_style").toByteArray();
|
||||
@ -106,14 +109,12 @@ void LXQtPlatformTheme::loadSettings() {
|
||||
if(!fontStr_.isEmpty()) {
|
||||
if(font_.fromString(fontStr_))
|
||||
QApplication::setFont(font_); // it seems that we need to do this manually.
|
||||
// qDebug() << "font: " << font_.toString();
|
||||
}
|
||||
|
||||
// FixedFont
|
||||
fixedFontStr_ = settings.value(QLatin1String("fixedFont")).toString();
|
||||
if(!fixedFontStr_.isEmpty()) {
|
||||
fixedFont_.fromString(fixedFontStr_);
|
||||
// qDebug() << "fixedFont: " << fixedFont_.toString();
|
||||
}
|
||||
|
||||
// mouse
|
||||
@ -165,8 +166,9 @@ void LXQtPlatformTheme::onSettingsChanged() {
|
||||
}
|
||||
|
||||
if(iconTheme_ != oldIconTheme) { // the icon theme is changed
|
||||
QIconLoader::instance()->updateSystemTheme(); // this is a private internal API of Qt5.
|
||||
XdgIconLoader::instance()->updateSystemTheme(); // this is a private internal API of Qt5.
|
||||
}
|
||||
XdgIconLoader::instance()->setFollowColorScheme(iconFollowColorScheme_);
|
||||
|
||||
// if font is changed
|
||||
if(oldFont != fontStr_ || oldFixedFont != fixedFontStr_){
|
||||
@ -187,6 +189,8 @@ void LXQtPlatformTheme::onSettingsChanged() {
|
||||
QApplication::setFont(font_);
|
||||
}
|
||||
|
||||
QApplication::setWheelScrollLines(wheelScrollLines_.toInt());
|
||||
|
||||
// emit a ThemeChange event to all widgets
|
||||
Q_FOREACH(QWidget* widget, QApplication::allWidgets()) {
|
||||
// Qt5 added a QEvent::ThemeChange event.
|
||||
@ -196,25 +200,29 @@ void LXQtPlatformTheme::onSettingsChanged() {
|
||||
}
|
||||
|
||||
bool LXQtPlatformTheme::usePlatformNativeDialog(DialogType type) const {
|
||||
if(type == FileDialog
|
||||
&& qobject_cast<QApplication *>(QCoreApplication::instance())) { // QML may not have qApp
|
||||
// use our own file dialog
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
QPlatformDialogHelper *LXQtPlatformTheme::createPlatformDialogHelper(DialogType type) const {
|
||||
return 0;
|
||||
if(type == FileDialog
|
||||
&& qobject_cast<QApplication *>(QCoreApplication::instance())) { // QML may not have qApp
|
||||
// use our own file dialog
|
||||
return new LXQtFileDialogHelper();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
const QPalette *LXQtPlatformTheme::palette(Palette type) const {
|
||||
|
||||
if (type == QPlatformTheme::SystemPalette)
|
||||
// the default constructor uses the default palette
|
||||
return new QPalette;
|
||||
return QPlatformTheme::palette(type);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const QFont *LXQtPlatformTheme::font(Font type) const {
|
||||
// qDebug() << "font()" << type << SystemFont;
|
||||
if(type == SystemFont && !fontStr_.isEmpty()) {
|
||||
// NOTE: for some reason, this is not called by Qt when program startup.
|
||||
// So we do QApplication::setFont() manually.
|
||||
@ -227,7 +235,6 @@ const QFont *LXQtPlatformTheme::font(Font type) const {
|
||||
}
|
||||
|
||||
QVariant LXQtPlatformTheme::themeHint(ThemeHint hint) const {
|
||||
// qDebug() << "themeHint" << hint;
|
||||
switch (hint) {
|
||||
case CursorFlashTime:
|
||||
return cursorFlashTime_;
|
||||
@ -258,14 +265,12 @@ QVariant LXQtPlatformTheme::themeHint(ThemeHint hint) const {
|
||||
case ItemViewActivateItemOnSingleClick:
|
||||
return QVariant(singleClickActivate_);
|
||||
case SystemIconThemeName:
|
||||
// qDebug() << "iconTheme" << iconTheme_;
|
||||
return iconTheme_;
|
||||
case SystemIconFallbackThemeName:
|
||||
return "hicolor";
|
||||
case IconThemeSearchPaths:
|
||||
return xdgIconThemePaths();
|
||||
case StyleNames:
|
||||
// qDebug() << "StyleNames";
|
||||
return QStringList() << style_;
|
||||
case WindowAutoPlacement:
|
||||
break;
|
||||
@ -291,35 +296,53 @@ QVariant LXQtPlatformTheme::themeHint(ThemeHint hint) const {
|
||||
break;
|
||||
case ContextMenuOnMouseRelease:
|
||||
break;
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 3, 0)
|
||||
// this was introduced in Qt 5.3.
|
||||
case MousePressAndHoldInterval:
|
||||
break;
|
||||
case MouseDoubleClickDistance:
|
||||
break;
|
||||
#endif
|
||||
case WheelScrollLines:
|
||||
return wheelScrollLines_;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QPlatformTheme::themeHint(hint);
|
||||
}
|
||||
|
||||
QIconEngine *LXQtPlatformTheme::createIconEngine(const QString &iconName) const
|
||||
{
|
||||
return new XdgIconLoaderEngine(iconName);
|
||||
}
|
||||
|
||||
// Helper to return the icon theme paths from XDG.
|
||||
QStringList LXQtPlatformTheme::xdgIconThemePaths() const
|
||||
{
|
||||
QStringList paths;
|
||||
QStringList xdgDirs;
|
||||
|
||||
// Add home directory first in search path
|
||||
const QFileInfo homeIconDir(QDir::homePath() + QStringLiteral("/.icons"));
|
||||
if (homeIconDir.isDir())
|
||||
paths.prepend(homeIconDir.absoluteFilePath());
|
||||
|
||||
QString xdgDirString = QFile::decodeName(qgetenv("XDG_DATA_DIRS"));
|
||||
if (xdgDirString.isEmpty())
|
||||
xdgDirString = QLatin1String("/usr/local/share/:/usr/share/");
|
||||
foreach (const QString &xdgDir, xdgDirString.split(QLatin1Char(':'))) {
|
||||
QString xdgDataHome = QFile::decodeName(qgetenv("XDG_DATA_HOME"));
|
||||
if (xdgDataHome.isEmpty())
|
||||
xdgDataHome = QDir::homePath() + QLatin1String("/.local/share");
|
||||
xdgDirs.append(xdgDataHome);
|
||||
|
||||
QString xdgDataDirs = QFile::decodeName(qgetenv("XDG_DATA_DIRS"));
|
||||
if (xdgDataDirs.isEmpty())
|
||||
xdgDataDirs = QLatin1String("/usr/local/share/:/usr/share/");
|
||||
xdgDirs.append(xdgDataDirs);
|
||||
|
||||
for (const auto &s: xdgDirs) {
|
||||
const QStringList r = s.split(QLatin1Char(':'), QString::SkipEmptyParts);
|
||||
for (const auto& xdgDir: r) {
|
||||
const QFileInfo xdgIconsDir(xdgDir + QStringLiteral("/icons"));
|
||||
if (xdgIconsDir.isDir())
|
||||
paths.append(xdgIconsDir.absoluteFilePath());
|
||||
}
|
||||
}
|
||||
paths.removeDuplicates();
|
||||
return paths;
|
||||
}
|
||||
|
@ -28,6 +28,8 @@
|
||||
#ifndef LXQTPLATFORMTHEME_H
|
||||
#define LXQTPLATFORMTHEME_H
|
||||
|
||||
#include "lxqtsystemtrayicon.h"
|
||||
|
||||
#include <qpa/qplatformtheme.h> // this private header is subject to changes
|
||||
#include <QtGlobal>
|
||||
#include <QVariant>
|
||||
@ -46,7 +48,7 @@ public:
|
||||
// virtual QPlatformMenuBar* createPlatformMenuBar() const;
|
||||
|
||||
virtual bool usePlatformNativeDialog(DialogType type) const;
|
||||
// virtual QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const;
|
||||
virtual QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const;
|
||||
|
||||
virtual const QPalette *palette(Palette type = SystemPalette) const;
|
||||
|
||||
@ -54,11 +56,23 @@ public:
|
||||
|
||||
virtual QVariant themeHint(ThemeHint hint) const;
|
||||
|
||||
QPlatformSystemTrayIcon *createPlatformSystemTrayIcon() const
|
||||
{
|
||||
auto trayIcon = new LXQtSystemTrayIcon;
|
||||
if (trayIcon->isSystemTrayAvailable())
|
||||
return trayIcon;
|
||||
else
|
||||
{
|
||||
delete trayIcon;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// virtual QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const;
|
||||
// virtual QPixmap fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size,
|
||||
// QPlatformTheme::IconOptions iconOptions = 0) const;
|
||||
|
||||
// virtual QIconEngine *createIconEngine(const QString &iconName) const;
|
||||
virtual QIconEngine *createIconEngine(const QString &iconName) const;
|
||||
|
||||
// virtual QList<QKeySequence> keyBindings(QKeySequence::StandardKey key) const;
|
||||
|
||||
@ -76,6 +90,7 @@ private:
|
||||
QString iconTheme_;
|
||||
Qt::ToolButtonStyle toolButtonStyle_;
|
||||
bool singleClickActivate_;
|
||||
bool iconFollowColorScheme_;
|
||||
|
||||
// other Qt settings
|
||||
// widget
|
||||
|
382
src/lxqtsystemtrayicon.cpp
Normal file
382
src/lxqtsystemtrayicon.cpp
Normal file
@ -0,0 +1,382 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://lxqt.org/
|
||||
*
|
||||
* Copyright: 2015 LXQt team
|
||||
* Authors:
|
||||
* 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 "lxqtsystemtrayicon.h"
|
||||
#include <QAction>
|
||||
#include <QIcon>
|
||||
#include <QMenu>
|
||||
#include <QRect>
|
||||
#include <QApplication>
|
||||
#include <QDBusMetaType>
|
||||
#include <QDBusInterface>
|
||||
|
||||
SystemTrayMenu::SystemTrayMenu()
|
||||
: QPlatformMenu(),
|
||||
m_tag(0),
|
||||
m_menu(new QMenu())
|
||||
{
|
||||
connect(m_menu.data(), &QMenu::aboutToShow, this, &QPlatformMenu::aboutToShow);
|
||||
connect(m_menu.data(), &QMenu::aboutToHide, this, &QPlatformMenu::aboutToHide);
|
||||
}
|
||||
|
||||
SystemTrayMenu::~SystemTrayMenu()
|
||||
{
|
||||
if (m_menu)
|
||||
m_menu->deleteLater();
|
||||
}
|
||||
|
||||
QPlatformMenuItem *SystemTrayMenu::createMenuItem() const
|
||||
{
|
||||
return new SystemTrayMenuItem();
|
||||
}
|
||||
|
||||
void SystemTrayMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before)
|
||||
{
|
||||
if (SystemTrayMenuItem *ours = qobject_cast<SystemTrayMenuItem*>(menuItem))
|
||||
{
|
||||
bool inserted = false;
|
||||
|
||||
if (SystemTrayMenuItem *oursBefore = qobject_cast<SystemTrayMenuItem*>(before))
|
||||
{
|
||||
for (auto it = m_items.begin(); it != m_items.end(); ++it)
|
||||
{
|
||||
if (*it == oursBefore)
|
||||
{
|
||||
m_items.insert(it, ours);
|
||||
if (m_menu)
|
||||
m_menu->insertAction(oursBefore->action(), ours->action());
|
||||
|
||||
inserted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!inserted)
|
||||
{
|
||||
m_items.append(ours);
|
||||
if (m_menu)
|
||||
m_menu->addAction(ours->action());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QPlatformMenuItem *SystemTrayMenu::menuItemAt(int position) const
|
||||
{
|
||||
if (position < m_items.size())
|
||||
return m_items.at(position);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QPlatformMenuItem *SystemTrayMenu::menuItemForTag(quintptr tag) const
|
||||
{
|
||||
auto it = std::find_if(m_items.constBegin(), m_items.constEnd(), [tag] (SystemTrayMenuItem *item)
|
||||
{
|
||||
return item->tag() == tag;
|
||||
});
|
||||
|
||||
if (it != m_items.constEnd())
|
||||
return *it;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SystemTrayMenu::removeMenuItem(QPlatformMenuItem *menuItem)
|
||||
{
|
||||
if (SystemTrayMenuItem *ours = qobject_cast<SystemTrayMenuItem*>(menuItem))
|
||||
{
|
||||
m_items.removeOne(ours);
|
||||
if (ours->action() && m_menu)
|
||||
m_menu->removeAction(ours->action());
|
||||
}
|
||||
}
|
||||
|
||||
void SystemTrayMenu::setEnabled(bool enabled)
|
||||
{
|
||||
if (!m_menu)
|
||||
return;
|
||||
|
||||
m_menu->setEnabled(enabled);
|
||||
}
|
||||
|
||||
void SystemTrayMenu::setIcon(const QIcon &icon)
|
||||
{
|
||||
if (!m_menu)
|
||||
return;
|
||||
|
||||
m_menu->setIcon(icon);
|
||||
}
|
||||
|
||||
void SystemTrayMenu::setTag(quintptr tag)
|
||||
{
|
||||
m_tag = tag;
|
||||
}
|
||||
|
||||
void SystemTrayMenu::setText(const QString &text)
|
||||
{
|
||||
if (!m_menu)
|
||||
return;
|
||||
|
||||
m_menu->setTitle(text);
|
||||
}
|
||||
|
||||
void SystemTrayMenu::setVisible(bool visible)
|
||||
{
|
||||
if (!m_menu)
|
||||
return;
|
||||
|
||||
m_menu->setVisible(visible);
|
||||
}
|
||||
|
||||
void SystemTrayMenu::syncMenuItem(QPlatformMenuItem *)
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
void SystemTrayMenu::syncSeparatorsCollapsible(bool enable)
|
||||
{
|
||||
if (!m_menu)
|
||||
return;
|
||||
|
||||
m_menu->setSeparatorsCollapsible(enable);
|
||||
}
|
||||
|
||||
quintptr SystemTrayMenu::tag() const
|
||||
{
|
||||
return m_tag;
|
||||
}
|
||||
|
||||
QMenu *SystemTrayMenu::menu() const
|
||||
{
|
||||
return m_menu.data();
|
||||
}
|
||||
|
||||
SystemTrayMenuItem::SystemTrayMenuItem()
|
||||
: QPlatformMenuItem(),
|
||||
m_tag(0),
|
||||
m_action(new QAction(this))
|
||||
{
|
||||
connect(m_action, &QAction::triggered, this, &QPlatformMenuItem::activated);
|
||||
connect(m_action, &QAction::hovered, this, &QPlatformMenuItem::hovered);
|
||||
}
|
||||
|
||||
SystemTrayMenuItem::~SystemTrayMenuItem()
|
||||
{
|
||||
}
|
||||
|
||||
void SystemTrayMenuItem::setCheckable(bool checkable)
|
||||
{
|
||||
m_action->setCheckable(checkable);
|
||||
}
|
||||
|
||||
void SystemTrayMenuItem::setChecked(bool isChecked)
|
||||
{
|
||||
m_action->setChecked(isChecked);
|
||||
}
|
||||
|
||||
void SystemTrayMenuItem::setEnabled(bool enabled)
|
||||
{
|
||||
m_action->setEnabled(enabled);
|
||||
}
|
||||
|
||||
void SystemTrayMenuItem::setFont(const QFont &font)
|
||||
{
|
||||
m_action->setFont(font);
|
||||
}
|
||||
|
||||
void SystemTrayMenuItem::setIcon(const QIcon &icon)
|
||||
{
|
||||
m_action->setIcon(icon);
|
||||
}
|
||||
|
||||
void SystemTrayMenuItem::setIsSeparator(bool isSeparator)
|
||||
{
|
||||
m_action->setSeparator(isSeparator);
|
||||
}
|
||||
|
||||
void SystemTrayMenuItem::setMenu(QPlatformMenu *menu)
|
||||
{
|
||||
if (SystemTrayMenu *ourMenu = qobject_cast<SystemTrayMenu *>(menu))
|
||||
m_action->setMenu(ourMenu->menu());
|
||||
}
|
||||
|
||||
void SystemTrayMenuItem::setRole(QPlatformMenuItem::MenuRole)
|
||||
{
|
||||
}
|
||||
|
||||
void SystemTrayMenuItem::setShortcut(const QKeySequence &shortcut)
|
||||
{
|
||||
m_action->setShortcut(shortcut);
|
||||
}
|
||||
|
||||
void SystemTrayMenuItem::setTag(quintptr tag)
|
||||
{
|
||||
m_tag = tag;
|
||||
}
|
||||
|
||||
void SystemTrayMenuItem::setText(const QString &text)
|
||||
{
|
||||
m_action->setText(text);
|
||||
}
|
||||
|
||||
void SystemTrayMenuItem::setVisible(bool isVisible)
|
||||
{
|
||||
m_action->setVisible(isVisible);
|
||||
}
|
||||
|
||||
void SystemTrayMenuItem::setIconSize(int)
|
||||
{
|
||||
}
|
||||
|
||||
quintptr SystemTrayMenuItem::tag() const
|
||||
{
|
||||
return m_tag;
|
||||
}
|
||||
|
||||
QAction *SystemTrayMenuItem::action() const
|
||||
{
|
||||
return m_action;
|
||||
}
|
||||
|
||||
LXQtSystemTrayIcon::LXQtSystemTrayIcon()
|
||||
: QPlatformSystemTrayIcon(),
|
||||
mSni(nullptr)
|
||||
{
|
||||
// register types
|
||||
qDBusRegisterMetaType<ToolTip>();
|
||||
qDBusRegisterMetaType<IconPixmap>();
|
||||
qDBusRegisterMetaType<IconPixmapList>();
|
||||
}
|
||||
|
||||
LXQtSystemTrayIcon::~LXQtSystemTrayIcon()
|
||||
{
|
||||
}
|
||||
|
||||
void LXQtSystemTrayIcon::init()
|
||||
{
|
||||
if (!mSni)
|
||||
{
|
||||
mSni = new StatusNotifierItem(QString::number(QCoreApplication::applicationPid()), this);
|
||||
mSni->setTitle(QApplication::applicationDisplayName());
|
||||
|
||||
// default menu
|
||||
QPlatformMenu *menu = createMenu();
|
||||
menu->setParent(mSni);
|
||||
QPlatformMenuItem *menuItem = menu->createMenuItem();
|
||||
menuItem->setParent(menu);
|
||||
menuItem->setText(tr("Quit"));
|
||||
menuItem->setIcon(QIcon::fromTheme("application-exit"));
|
||||
connect(menuItem, &QPlatformMenuItem::activated, qApp, &QApplication::quit);
|
||||
menu->insertMenuItem(menuItem, nullptr);
|
||||
updateMenu(menu);
|
||||
|
||||
connect(mSni, &StatusNotifierItem::activateRequested, [this](const QPoint &)
|
||||
{
|
||||
Q_EMIT activated(QPlatformSystemTrayIcon::Trigger);
|
||||
});
|
||||
|
||||
connect(mSni, &StatusNotifierItem::secondaryActivateRequested, [this](const QPoint &)
|
||||
{
|
||||
Q_EMIT activated(QPlatformSystemTrayIcon::MiddleClick);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void LXQtSystemTrayIcon::cleanup()
|
||||
{
|
||||
delete mSni;
|
||||
mSni = nullptr;
|
||||
}
|
||||
|
||||
void LXQtSystemTrayIcon::updateIcon(const QIcon &icon)
|
||||
{
|
||||
if (!mSni)
|
||||
return;
|
||||
|
||||
if (icon.name().isEmpty())
|
||||
{
|
||||
mSni->setIconByPixmap(icon);
|
||||
mSni->setToolTipIconByPixmap(icon);
|
||||
}
|
||||
else
|
||||
{
|
||||
mSni->setIconByName(icon.name());
|
||||
mSni->setToolTipIconByName(icon.name());
|
||||
}
|
||||
}
|
||||
|
||||
void LXQtSystemTrayIcon::updateToolTip(const QString &tooltip)
|
||||
{
|
||||
if (!mSni)
|
||||
return;
|
||||
|
||||
mSni->setToolTipTitle(tooltip);
|
||||
}
|
||||
|
||||
void LXQtSystemTrayIcon::updateMenu(QPlatformMenu *menu)
|
||||
{
|
||||
if (!mSni)
|
||||
return;
|
||||
|
||||
if (SystemTrayMenu *ourMenu = qobject_cast<SystemTrayMenu*>(menu))
|
||||
mSni->setContextMenu(ourMenu->menu());
|
||||
}
|
||||
|
||||
QPlatformMenu *LXQtSystemTrayIcon::createMenu() const
|
||||
{
|
||||
return new SystemTrayMenu();
|
||||
}
|
||||
|
||||
QRect LXQtSystemTrayIcon::geometry() const
|
||||
{
|
||||
// StatusNotifierItem doesn't provide the geometry
|
||||
return QRect();
|
||||
}
|
||||
|
||||
void LXQtSystemTrayIcon::showMessage(const QString &title, const QString &msg,
|
||||
const QIcon &icon, MessageIcon, int secs)
|
||||
{
|
||||
if (!mSni)
|
||||
return;
|
||||
|
||||
mSni->showMessage(title, msg, icon.name(), secs);
|
||||
}
|
||||
|
||||
bool LXQtSystemTrayIcon::isSystemTrayAvailable() const
|
||||
{
|
||||
QDBusInterface systrayHost("org.kde.StatusNotifierWatcher",
|
||||
"/StatusNotifierWatcher",
|
||||
"org.kde.StatusNotifierWatcher");
|
||||
|
||||
return systrayHost.isValid() && systrayHost.property("IsStatusNotifierHostRegistered").toBool();
|
||||
}
|
||||
|
||||
bool LXQtSystemTrayIcon::supportsMessages() const
|
||||
{
|
||||
return true;
|
||||
}
|
124
src/lxqtsystemtrayicon.h
Normal file
124
src/lxqtsystemtrayicon.h
Normal file
@ -0,0 +1,124 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://lxqt.org/
|
||||
*
|
||||
* Copyright: 2015 LXQt team
|
||||
* Authors:
|
||||
* 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 LXQTSYSTEMTRAYICON_H
|
||||
#define LXQTSYSTEMTRAYICON_H
|
||||
|
||||
#include <qpa/qplatformmenu.h>
|
||||
#include <qpa/qplatformsystemtrayicon.h>
|
||||
|
||||
#include "statusnotifieritem/statusnotifieritem.h"
|
||||
|
||||
class SystemTrayMenuItem;
|
||||
class QAction;
|
||||
class QMenu;
|
||||
|
||||
class SystemTrayMenu : public QPlatformMenu
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SystemTrayMenu();
|
||||
~SystemTrayMenu() Q_DECL_OVERRIDE;
|
||||
void insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) Q_DECL_OVERRIDE;
|
||||
QPlatformMenuItem *menuItemAt(int position) const Q_DECL_OVERRIDE;
|
||||
QPlatformMenuItem *menuItemForTag(quintptr tag) const Q_DECL_OVERRIDE;
|
||||
void removeMenuItem(QPlatformMenuItem *menuItem) Q_DECL_OVERRIDE;
|
||||
void setEnabled(bool enabled) Q_DECL_OVERRIDE;
|
||||
void setIcon(const QIcon &icon) Q_DECL_OVERRIDE;
|
||||
void setTag(quintptr tag) Q_DECL_OVERRIDE;
|
||||
void setText(const QString &text) Q_DECL_OVERRIDE;
|
||||
void setVisible(bool visible) Q_DECL_OVERRIDE;
|
||||
void syncMenuItem(QPlatformMenuItem *menuItem) Q_DECL_OVERRIDE;
|
||||
void syncSeparatorsCollapsible(bool enable) Q_DECL_OVERRIDE;
|
||||
quintptr tag() const Q_DECL_OVERRIDE;
|
||||
QPlatformMenuItem *createMenuItem() const Q_DECL_OVERRIDE;
|
||||
|
||||
QMenu *menu() const;
|
||||
|
||||
private:
|
||||
quintptr m_tag;
|
||||
QPointer<QMenu> m_menu;
|
||||
QList<SystemTrayMenuItem*> m_items;
|
||||
};
|
||||
|
||||
class SystemTrayMenuItem : public QPlatformMenuItem
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SystemTrayMenuItem();
|
||||
~SystemTrayMenuItem() Q_DECL_OVERRIDE;
|
||||
void setCheckable(bool checkable) Q_DECL_OVERRIDE;
|
||||
void setChecked(bool isChecked) Q_DECL_OVERRIDE;
|
||||
void setEnabled(bool enabled) Q_DECL_OVERRIDE;
|
||||
void setFont(const QFont &font) Q_DECL_OVERRIDE;
|
||||
void setIcon(const QIcon &icon) Q_DECL_OVERRIDE;
|
||||
void setIsSeparator(bool isSeparator) Q_DECL_OVERRIDE;
|
||||
void setMenu(QPlatformMenu *menu) Q_DECL_OVERRIDE;
|
||||
void setRole(MenuRole role) Q_DECL_OVERRIDE;
|
||||
void setShortcut(const QKeySequence &shortcut) Q_DECL_OVERRIDE;
|
||||
void setTag(quintptr tag) Q_DECL_OVERRIDE;
|
||||
void setText(const QString &text) Q_DECL_OVERRIDE;
|
||||
void setVisible(bool isVisible) Q_DECL_OVERRIDE;
|
||||
quintptr tag() const Q_DECL_OVERRIDE;
|
||||
void setIconSize(int size)
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0))
|
||||
Q_DECL_OVERRIDE
|
||||
#endif
|
||||
;
|
||||
|
||||
QAction *action() const;
|
||||
|
||||
private:
|
||||
quintptr m_tag;
|
||||
QAction *m_action;
|
||||
};
|
||||
|
||||
class LXQtSystemTrayIcon : public QPlatformSystemTrayIcon
|
||||
{
|
||||
public:
|
||||
LXQtSystemTrayIcon();
|
||||
~LXQtSystemTrayIcon() Q_DECL_OVERRIDE;
|
||||
|
||||
void init() Q_DECL_OVERRIDE;
|
||||
void cleanup() Q_DECL_OVERRIDE;
|
||||
void updateIcon(const QIcon &icon) Q_DECL_OVERRIDE;
|
||||
void updateToolTip(const QString &tooltip) Q_DECL_OVERRIDE;
|
||||
void updateMenu(QPlatformMenu *menu) Q_DECL_OVERRIDE;
|
||||
QRect geometry() const Q_DECL_OVERRIDE;
|
||||
void showMessage(const QString &title, const QString &msg,
|
||||
const QIcon &icon, MessageIcon iconType, int secs) Q_DECL_OVERRIDE;
|
||||
|
||||
bool isSystemTrayAvailable() const Q_DECL_OVERRIDE;
|
||||
bool supportsMessages() const Q_DECL_OVERRIDE;
|
||||
|
||||
QPlatformMenu *createMenu() const Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
StatusNotifierItem *mSni;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,194 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtGui module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QICONLOADER_P_H
|
||||
#define QICONLOADER_P_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#ifndef QT_NO_ICON
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtGui/QIcon>
|
||||
#include <QtGui/QIconEngine>
|
||||
#include <QtGui/QPixmapCache>
|
||||
#include <private/qicon_p.h>
|
||||
#include <private/qfactoryloader_p.h>
|
||||
#include <QtCore/QHash>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QIconLoader;
|
||||
|
||||
struct QIconDirInfo
|
||||
{
|
||||
enum Type { Fixed, Scalable, Threshold };
|
||||
QIconDirInfo(const QString &_path = QString()) :
|
||||
path(_path),
|
||||
size(0),
|
||||
maxSize(0),
|
||||
minSize(0),
|
||||
threshold(0),
|
||||
type(Threshold) {}
|
||||
QString path;
|
||||
short size;
|
||||
short maxSize;
|
||||
short minSize;
|
||||
short threshold;
|
||||
Type type : 4;
|
||||
};
|
||||
|
||||
class QIconLoaderEngineEntry
|
||||
{
|
||||
public:
|
||||
virtual ~QIconLoaderEngineEntry() {}
|
||||
virtual QPixmap pixmap(const QSize &size,
|
||||
QIcon::Mode mode,
|
||||
QIcon::State state) = 0;
|
||||
QString filename;
|
||||
QIconDirInfo dir;
|
||||
static int count;
|
||||
};
|
||||
|
||||
struct ScalableEntry : public QIconLoaderEngineEntry
|
||||
{
|
||||
QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state);
|
||||
QIcon svgIcon;
|
||||
};
|
||||
|
||||
struct PixmapEntry : public QIconLoaderEngineEntry
|
||||
{
|
||||
QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state);
|
||||
QPixmap basePixmap;
|
||||
};
|
||||
|
||||
typedef QList<QIconLoaderEngineEntry*> QThemeIconEntries;
|
||||
|
||||
class QIconLoaderEngine : public QIconEngine
|
||||
{
|
||||
public:
|
||||
QIconLoaderEngine(const QString& iconName = QString());
|
||||
~QIconLoaderEngine();
|
||||
|
||||
void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state);
|
||||
QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state);
|
||||
QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state);
|
||||
QIconEngine *clone() const;
|
||||
bool read(QDataStream &in);
|
||||
bool write(QDataStream &out) const;
|
||||
|
||||
private:
|
||||
QString key() const;
|
||||
bool hasIcon() const;
|
||||
void ensureLoaded();
|
||||
void virtual_hook(int id, void *data);
|
||||
QIconLoaderEngineEntry *entryForSize(const QSize &size);
|
||||
QIconLoaderEngine(const QIconLoaderEngine &other);
|
||||
QThemeIconEntries m_entries;
|
||||
QString m_iconName;
|
||||
uint m_key;
|
||||
|
||||
friend class QIconLoader;
|
||||
};
|
||||
|
||||
class QIconTheme
|
||||
{
|
||||
public:
|
||||
QIconTheme(const QString &name);
|
||||
QIconTheme() : m_valid(false) {}
|
||||
QStringList parents() { return m_parents; }
|
||||
QList <QIconDirInfo> keyList() { return m_keyList; }
|
||||
QString contentDir() { return m_contentDir; }
|
||||
bool isValid() { return m_valid; }
|
||||
|
||||
private:
|
||||
QString m_contentDir;
|
||||
QList <QIconDirInfo> m_keyList;
|
||||
QStringList m_parents;
|
||||
bool m_valid;
|
||||
};
|
||||
|
||||
class Q_GUI_EXPORT QIconLoader : public QObject
|
||||
{
|
||||
public:
|
||||
QIconLoader();
|
||||
QThemeIconEntries loadIcon(const QString &iconName) const;
|
||||
uint themeKey() const { return m_themeKey; }
|
||||
|
||||
QString themeName() const { return m_userTheme.isEmpty() ? m_systemTheme : m_userTheme; }
|
||||
void setThemeName(const QString &themeName);
|
||||
QIconTheme theme() { return themeList.value(themeName()); }
|
||||
void setThemeSearchPath(const QStringList &searchPaths);
|
||||
QStringList themeSearchPaths() const;
|
||||
QIconDirInfo dirInfo(int dirindex);
|
||||
static QIconLoader *instance();
|
||||
void updateSystemTheme();
|
||||
void invalidateKey() { m_themeKey++; }
|
||||
void ensureInitialized();
|
||||
|
||||
private:
|
||||
QThemeIconEntries findIconHelper(const QString &themeName,
|
||||
const QString &iconName,
|
||||
QStringList &visited) const;
|
||||
uint m_themeKey;
|
||||
bool m_supportsSvg;
|
||||
bool m_initialized;
|
||||
|
||||
mutable QString m_userTheme;
|
||||
mutable QString m_systemTheme;
|
||||
mutable QStringList m_iconDirs;
|
||||
mutable QHash <QString, QIconTheme> themeList;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_ICON
|
||||
|
||||
#endif // QICONLOADER_P_H
|
75
src/statusnotifieritem/dbustypes.cpp
Normal file
75
src/statusnotifieritem/dbustypes.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXDE-Qt - a lightweight, Qt based, desktop toolset
|
||||
* http://lxqt.org
|
||||
*
|
||||
* Copyright: 2015 LXQt team
|
||||
* Authors:
|
||||
* Balázs Béla <balazsbela[at]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 "dbustypes.h"
|
||||
|
||||
// Marshall the IconPixmap data into a D-Bus argument
|
||||
QDBusArgument &operator<<(QDBusArgument &argument, const IconPixmap &icon)
|
||||
{
|
||||
argument.beginStructure();
|
||||
argument << icon.width;
|
||||
argument << icon.height;
|
||||
argument << icon.bytes;
|
||||
argument.endStructure();
|
||||
return argument;
|
||||
}
|
||||
|
||||
// Retrieve the ImageStruct data from the D-Bus argument
|
||||
const QDBusArgument &operator>>(const QDBusArgument &argument, IconPixmap &icon)
|
||||
{
|
||||
argument.beginStructure();
|
||||
argument >> icon.width;
|
||||
argument >> icon.height;
|
||||
argument >> icon.bytes;
|
||||
argument.endStructure();
|
||||
return argument;
|
||||
}
|
||||
|
||||
// Marshall the ToolTip data into a D-Bus argument
|
||||
QDBusArgument &operator<<(QDBusArgument &argument, const ToolTip &toolTip)
|
||||
{
|
||||
argument.beginStructure();
|
||||
argument << toolTip.iconName;
|
||||
argument << toolTip.iconPixmap;
|
||||
argument << toolTip.title;
|
||||
argument << toolTip.description;
|
||||
argument.endStructure();
|
||||
return argument;
|
||||
}
|
||||
|
||||
// Retrieve the ToolTip data from the D-Bus argument
|
||||
const QDBusArgument &operator>>(const QDBusArgument &argument, ToolTip &toolTip)
|
||||
{
|
||||
argument.beginStructure();
|
||||
argument >> toolTip.iconName;
|
||||
argument >> toolTip.iconPixmap;
|
||||
argument >> toolTip.title;
|
||||
argument >> toolTip.description;
|
||||
argument.endStructure();
|
||||
return argument;
|
||||
}
|
60
src/statusnotifieritem/dbustypes.h
Normal file
60
src/statusnotifieritem/dbustypes.h
Normal file
@ -0,0 +1,60 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXDE-Qt - a lightweight, Qt based, desktop toolset
|
||||
* http://lxqt.org
|
||||
*
|
||||
* Copyright: 2015 LXQt team
|
||||
* Authors:
|
||||
* Balázs Béla <balazsbela[at]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 <QDBusArgument>
|
||||
|
||||
#ifndef DBUSTYPES_H
|
||||
#define DBUSTYPES_H
|
||||
|
||||
struct IconPixmap {
|
||||
int width;
|
||||
int height;
|
||||
QByteArray bytes;
|
||||
};
|
||||
|
||||
typedef QList<IconPixmap> IconPixmapList;
|
||||
|
||||
Q_DECLARE_METATYPE(IconPixmap)
|
||||
Q_DECLARE_METATYPE(IconPixmapList)
|
||||
|
||||
struct ToolTip {
|
||||
QString iconName;
|
||||
QList<IconPixmap> iconPixmap;
|
||||
QString title;
|
||||
QString description;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(ToolTip)
|
||||
|
||||
QDBusArgument &operator<<(QDBusArgument &argument, const IconPixmap &icon);
|
||||
const QDBusArgument &operator>>(const QDBusArgument &argument, IconPixmap &icon);
|
||||
|
||||
QDBusArgument &operator<<(QDBusArgument &argument, const ToolTip &toolTip);
|
||||
const QDBusArgument &operator>>(const QDBusArgument &argument, ToolTip &toolTip);
|
||||
|
||||
#endif // DBUSTYPES_H
|
69
src/statusnotifieritem/org.kde.StatusNotifierItem.xml
Normal file
69
src/statusnotifieritem/org.kde.StatusNotifierItem.xml
Normal file
@ -0,0 +1,69 @@
|
||||
<!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.kde.StatusNotifierItem">
|
||||
|
||||
<property name="Category" type="s" access="read"/>
|
||||
<property name="Id" type="s" access="read"/>
|
||||
<property name="Title" type="s" access="read"/>
|
||||
<property name="Status" type="s" access="read"/>
|
||||
<property name="WindowId" type="i" access="read"/>
|
||||
<property name="IconThemePath" type="s" access="read"/>
|
||||
<property name="Menu" type="o" access="read"/>
|
||||
<property name="ItemIsMenu" type="b" access="read"/>
|
||||
<property name="IconName" type="s" access="read"/>
|
||||
<property name="IconPixmap" type="a(iiay)" access="read">
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName" value="IconPixmapList"/>
|
||||
</property>
|
||||
<property name="OverlayIconName" type="s" access="read"/>
|
||||
<property name="OverlayIconPixmap" type="a(iiay)" access="read">
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName" value="IconPixmapList"/>
|
||||
</property>
|
||||
<property name="AttentionIconName" type="s" access="read"/>
|
||||
<property name="AttentionIconPixmap" type="a(iiay)" access="read">
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName" value="IconPixmapList"/>
|
||||
</property>
|
||||
<property name="AttentionMovieName" type="s" access="read"/>
|
||||
<property name="ToolTip" type="(sa(iiay)ss)" access="read">
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName" value="ToolTip"/>
|
||||
</property>
|
||||
<method name="ContextMenu">
|
||||
<arg name="x" type="i" direction="in"/>
|
||||
<arg name="y" type="i" direction="in"/>
|
||||
</method>
|
||||
|
||||
<method name="Activate">
|
||||
<arg name="x" type="i" direction="in"/>
|
||||
<arg name="y" type="i" direction="in"/>
|
||||
</method>
|
||||
|
||||
<method name="SecondaryActivate">
|
||||
<arg name="x" type="i" direction="in"/>
|
||||
<arg name="y" type="i" direction="in"/>
|
||||
</method>
|
||||
|
||||
<method name="Scroll">
|
||||
<arg name="delta" type="i" direction="in"/>
|
||||
<arg name="orientation" type="s" direction="in"/>
|
||||
</method>
|
||||
|
||||
<signal name="NewTitle">
|
||||
</signal>
|
||||
|
||||
<signal name="NewIcon">
|
||||
</signal>
|
||||
|
||||
<signal name="NewAttentionIcon">
|
||||
</signal>
|
||||
|
||||
<signal name="NewOverlayIcon">
|
||||
</signal>
|
||||
|
||||
<signal name="NewToolTip">
|
||||
</signal>
|
||||
|
||||
<signal name="NewStatus">
|
||||
<arg name="status" type="s"/>
|
||||
</signal>
|
||||
|
||||
</interface>
|
||||
</node>
|
322
src/statusnotifieritem/statusnotifieritem.cpp
Normal file
322
src/statusnotifieritem/statusnotifieritem.cpp
Normal file
@ -0,0 +1,322 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://lxqt.org/
|
||||
*
|
||||
* Copyright: 2015 LXQt team
|
||||
* Authors:
|
||||
* 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 "statusnotifieritem.h"
|
||||
#include "statusnotifieritemadaptor.h"
|
||||
#include <QDBusInterface>
|
||||
#include <QDBusServiceWatcher>
|
||||
#include <dbusmenu-qt5/dbusmenuexporter.h>
|
||||
|
||||
int StatusNotifierItem::mServiceCounter = 0;
|
||||
|
||||
StatusNotifierItem::StatusNotifierItem(QString id, QObject *parent)
|
||||
: QObject(parent),
|
||||
mAdaptor(new StatusNotifierItemAdaptor(this)),
|
||||
mService(QString("org.freedesktop.StatusNotifierItem-%1-%2")
|
||||
.arg(QCoreApplication::applicationPid())
|
||||
.arg(++mServiceCounter)),
|
||||
mId(id),
|
||||
mTitle("Test"),
|
||||
mStatus("Active"),
|
||||
mMenu(nullptr),
|
||||
mMenuExporter(nullptr),
|
||||
mSessionBus(QDBusConnection::connectToBus(QDBusConnection::SessionBus, mService))
|
||||
{
|
||||
// Separate DBus connection to the session bus is created, because QDbus does not provide
|
||||
// a way to register different objects for different services with the same paths.
|
||||
// For status notifiers we need different /StatusNotifierItem for each service.
|
||||
|
||||
// register service
|
||||
|
||||
mSessionBus.registerService(mService);
|
||||
mSessionBus.registerObject(QLatin1String("/StatusNotifierItem"), this);
|
||||
|
||||
registerToHost();
|
||||
|
||||
// monitor the watcher service in case the host restarts
|
||||
QDBusServiceWatcher *watcher = new QDBusServiceWatcher("org.kde.StatusNotifierWatcher",
|
||||
mSessionBus,
|
||||
QDBusServiceWatcher::WatchForOwnerChange,
|
||||
this);
|
||||
connect(watcher, &QDBusServiceWatcher::serviceOwnerChanged,
|
||||
this, &StatusNotifierItem::onServiceOwnerChanged);
|
||||
}
|
||||
|
||||
StatusNotifierItem::~StatusNotifierItem()
|
||||
{
|
||||
mSessionBus.unregisterObject(QLatin1String("/StatusNotifierItem"));
|
||||
mSessionBus.unregisterService(mService);
|
||||
QDBusConnection::disconnectFromBus(mService);
|
||||
}
|
||||
|
||||
void StatusNotifierItem::registerToHost()
|
||||
{
|
||||
QDBusInterface interface("org.kde.StatusNotifierWatcher",
|
||||
"/StatusNotifierWatcher",
|
||||
"org.kde.StatusNotifierWatcher",
|
||||
mSessionBus);
|
||||
interface.asyncCall("RegisterStatusNotifierItem", mService);
|
||||
}
|
||||
|
||||
void StatusNotifierItem::onServiceOwnerChanged(const QString& service, const QString& oldOwner,
|
||||
const QString& newOwner)
|
||||
{
|
||||
Q_UNUSED(service);
|
||||
Q_UNUSED(oldOwner);
|
||||
|
||||
if (!newOwner.isEmpty())
|
||||
registerToHost();
|
||||
}
|
||||
|
||||
void StatusNotifierItem::onMenuDestroyed()
|
||||
{
|
||||
mMenu = nullptr;
|
||||
mMenuExporter = nullptr; //mMenu is a QObject parent of the mMenuExporter
|
||||
}
|
||||
|
||||
void StatusNotifierItem::setTitle(const QString &title)
|
||||
{
|
||||
if (mTitle == title)
|
||||
return;
|
||||
|
||||
mTitle = title;
|
||||
Q_EMIT mAdaptor->NewTitle();
|
||||
}
|
||||
|
||||
void StatusNotifierItem::setStatus(const QString &status)
|
||||
{
|
||||
if (mStatus == status)
|
||||
return;
|
||||
|
||||
mStatus = status;
|
||||
Q_EMIT mAdaptor->NewStatus(mStatus);
|
||||
}
|
||||
|
||||
void StatusNotifierItem::setMenuPath(const QString& path)
|
||||
{
|
||||
mMenuPath.setPath(path);
|
||||
}
|
||||
|
||||
void StatusNotifierItem::setIconByName(const QString &name)
|
||||
{
|
||||
if (mIconName == name)
|
||||
return;
|
||||
|
||||
mIconName = name;
|
||||
Q_EMIT mAdaptor->NewIcon();
|
||||
}
|
||||
|
||||
void StatusNotifierItem::setIconByPixmap(const QIcon &icon)
|
||||
{
|
||||
if (mIconCacheKey == icon.cacheKey())
|
||||
return;
|
||||
|
||||
mIconCacheKey = icon.cacheKey();
|
||||
mIcon = iconToPixmapList(icon);
|
||||
mIconName.clear();
|
||||
Q_EMIT mAdaptor->NewIcon();
|
||||
}
|
||||
|
||||
void StatusNotifierItem::setOverlayIconByName(const QString &name)
|
||||
{
|
||||
if (mOverlayIconName == name)
|
||||
return;
|
||||
|
||||
mOverlayIconName = name;
|
||||
Q_EMIT mAdaptor->NewOverlayIcon();
|
||||
}
|
||||
|
||||
void StatusNotifierItem::setOverlayIconByPixmap(const QIcon &icon)
|
||||
{
|
||||
if (mOverlayIconCacheKey == icon.cacheKey())
|
||||
return;
|
||||
|
||||
mOverlayIconCacheKey = icon.cacheKey();
|
||||
mOverlayIcon = iconToPixmapList(icon);
|
||||
mOverlayIconName.clear();
|
||||
Q_EMIT mAdaptor->NewOverlayIcon();
|
||||
}
|
||||
|
||||
void StatusNotifierItem::setAttentionIconByName(const QString &name)
|
||||
{
|
||||
if (mAttentionIconName == name)
|
||||
return;
|
||||
|
||||
mAttentionIconName = name;
|
||||
Q_EMIT mAdaptor->NewAttentionIcon();
|
||||
}
|
||||
|
||||
void StatusNotifierItem::setAttentionIconByPixmap(const QIcon &icon)
|
||||
{
|
||||
if (mAttentionIconCacheKey == icon.cacheKey())
|
||||
return;
|
||||
|
||||
mAttentionIconCacheKey = icon.cacheKey();
|
||||
mAttentionIcon = iconToPixmapList(icon);
|
||||
mAttentionIconName.clear();
|
||||
Q_EMIT mAdaptor->NewAttentionIcon();
|
||||
}
|
||||
|
||||
void StatusNotifierItem::setToolTipTitle(const QString &title)
|
||||
{
|
||||
if (mTooltipTitle == title)
|
||||
return;
|
||||
|
||||
mTooltipTitle = title;
|
||||
Q_EMIT mAdaptor->NewToolTip();
|
||||
}
|
||||
|
||||
void StatusNotifierItem::setToolTipSubTitle(const QString &subTitle)
|
||||
{
|
||||
if (mTooltipSubtitle == subTitle)
|
||||
return;
|
||||
|
||||
mTooltipSubtitle = subTitle;
|
||||
Q_EMIT mAdaptor->NewToolTip();
|
||||
}
|
||||
|
||||
void StatusNotifierItem::setToolTipIconByName(const QString &name)
|
||||
{
|
||||
if (mTooltipIconName == name)
|
||||
return;
|
||||
|
||||
mTooltipIconName = name;
|
||||
Q_EMIT mAdaptor->NewToolTip();
|
||||
}
|
||||
|
||||
void StatusNotifierItem::setToolTipIconByPixmap(const QIcon &icon)
|
||||
{
|
||||
if (mTooltipIconCacheKey == icon.cacheKey())
|
||||
return;
|
||||
|
||||
mTooltipIconCacheKey = icon.cacheKey();
|
||||
mTooltipIcon = iconToPixmapList(icon);
|
||||
mTooltipIconName.clear();
|
||||
Q_EMIT mAdaptor->NewToolTip();
|
||||
}
|
||||
|
||||
void StatusNotifierItem::setContextMenu(QMenu* menu)
|
||||
{
|
||||
if (mMenu == menu)
|
||||
return;
|
||||
|
||||
if (nullptr != mMenu)
|
||||
{
|
||||
disconnect(mMenu, &QObject::destroyed, this, &StatusNotifierItem::onMenuDestroyed);
|
||||
}
|
||||
mMenu = menu;
|
||||
|
||||
setMenuPath("/MenuBar");
|
||||
//Note: we need to destroy menu exporter before creating new one -> to free the DBus object path for new menu
|
||||
delete mMenuExporter;
|
||||
if (nullptr != mMenu)
|
||||
{
|
||||
connect(mMenu, &QObject::destroyed, this, &StatusNotifierItem::onMenuDestroyed);
|
||||
mMenuExporter = new DBusMenuExporter{this->menu().path(), mMenu, mSessionBus};
|
||||
}
|
||||
}
|
||||
|
||||
void StatusNotifierItem::Activate(int x, int y)
|
||||
{
|
||||
if (mStatus == "NeedsAttention")
|
||||
mStatus = "Active";
|
||||
|
||||
Q_EMIT activateRequested(QPoint(x, y));
|
||||
}
|
||||
|
||||
void StatusNotifierItem::SecondaryActivate(int x, int y)
|
||||
{
|
||||
if (mStatus == "NeedsAttention")
|
||||
mStatus = "Active";
|
||||
|
||||
Q_EMIT secondaryActivateRequested(QPoint(x, y));
|
||||
}
|
||||
|
||||
void StatusNotifierItem::ContextMenu(int x, int y)
|
||||
{
|
||||
if (mMenu)
|
||||
{
|
||||
if (mMenu->isVisible())
|
||||
mMenu->popup(QPoint(x, y));
|
||||
else
|
||||
mMenu->hide();
|
||||
}
|
||||
}
|
||||
|
||||
void StatusNotifierItem::Scroll(int delta, const QString &orientation)
|
||||
{
|
||||
Qt::Orientation orient = Qt::Vertical;
|
||||
if (orientation.toLower() == "horizontal")
|
||||
orient = Qt::Horizontal;
|
||||
|
||||
Q_EMIT scrollRequested(delta, orient);
|
||||
}
|
||||
|
||||
void StatusNotifierItem::showMessage(const QString& title, const QString& msg,
|
||||
const QString& iconName, int secs)
|
||||
{
|
||||
QDBusInterface interface("org.freedesktop.Notifications", "/org/freedesktop/Notifications",
|
||||
"org.freedesktop.Notifications", mSessionBus);
|
||||
interface.call("Notify", mTitle, (uint) 0, iconName, title,
|
||||
msg, QStringList(), QVariantMap(), secs);
|
||||
}
|
||||
|
||||
IconPixmapList StatusNotifierItem::iconToPixmapList(const QIcon& icon)
|
||||
{
|
||||
IconPixmapList pixmapList;
|
||||
|
||||
// long live KDE!
|
||||
const QList<QSize> sizes = icon.availableSizes();
|
||||
for (const QSize &size : sizes)
|
||||
{
|
||||
QImage image = icon.pixmap(size).toImage();
|
||||
|
||||
IconPixmap pix;
|
||||
pix.height = image.height();
|
||||
pix.width = image.width();
|
||||
|
||||
if (image.format() != QImage::Format_ARGB32)
|
||||
image = image.convertToFormat(QImage::Format_ARGB32);
|
||||
|
||||
pix.bytes = QByteArray((char *) image.bits(), image.byteCount());
|
||||
|
||||
// swap to network byte order if we are little endian
|
||||
if (QSysInfo::ByteOrder == QSysInfo::LittleEndian)
|
||||
{
|
||||
quint32 *uintBuf = (quint32 *) pix.bytes.data();
|
||||
for (uint i = 0; i < pix.bytes.size() / sizeof(quint32); ++i)
|
||||
{
|
||||
*uintBuf = qToBigEndian(*uintBuf);
|
||||
++uintBuf;
|
||||
}
|
||||
}
|
||||
|
||||
pixmapList.append(pix);
|
||||
}
|
||||
|
||||
return pixmapList;
|
||||
}
|
185
src/statusnotifieritem/statusnotifieritem.h
Normal file
185
src/statusnotifieritem/statusnotifieritem.h
Normal file
@ -0,0 +1,185 @@
|
||||
/* BEGIN_COMMON_COPYRIGHT_HEADER
|
||||
* (c)LGPL2+
|
||||
*
|
||||
* LXQt - a lightweight, Qt based, desktop toolset
|
||||
* http://lxqt.org/
|
||||
*
|
||||
* Copyright: 2015 LXQt team
|
||||
* Authors:
|
||||
* 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 STATUS_NOTIFIER_ITEM_H
|
||||
#define STATUS_NOTIFIER_ITEM_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QIcon>
|
||||
#include <QMenu>
|
||||
#include <QDBusConnection>
|
||||
|
||||
#include "dbustypes.h"
|
||||
|
||||
class StatusNotifierItemAdaptor;
|
||||
class DBusMenuExporter;
|
||||
|
||||
class StatusNotifierItem : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString Title READ title)
|
||||
Q_PROPERTY(QString Id READ id)
|
||||
Q_PROPERTY(QString Status READ status)
|
||||
Q_PROPERTY(QDBusObjectPath Menu READ menu)
|
||||
|
||||
Q_PROPERTY(QString IconName READ iconName)
|
||||
Q_PROPERTY(IconPixmapList IconPixmap READ iconPixmap)
|
||||
|
||||
Q_PROPERTY(QString OverlayIconName READ overlayIconName)
|
||||
Q_PROPERTY(IconPixmapList OverlayIconPixmap READ overlayIconPixmap)
|
||||
|
||||
Q_PROPERTY(QString AttentionIconName READ attentionIconName)
|
||||
Q_PROPERTY(IconPixmapList AttentionIconPixmap READ attentionIconPixmap)
|
||||
|
||||
Q_PROPERTY(ToolTip ToolTip READ toolTip)
|
||||
|
||||
public:
|
||||
StatusNotifierItem(QString id, QObject *parent = nullptr);
|
||||
~StatusNotifierItem();
|
||||
|
||||
QString id() const
|
||||
{ return mId; }
|
||||
|
||||
QString title() const
|
||||
{ return mTitle; }
|
||||
void setTitle(const QString &title);
|
||||
|
||||
QString status() const
|
||||
{ return mStatus; }
|
||||
void setStatus(const QString &status);
|
||||
|
||||
QDBusObjectPath menu() const
|
||||
{ return mMenuPath; }
|
||||
void setMenuPath(const QString &path);
|
||||
|
||||
QString iconName() const
|
||||
{ return mIconName; }
|
||||
void setIconByName(const QString &name);
|
||||
|
||||
IconPixmapList iconPixmap() const
|
||||
{ return mIcon; }
|
||||
void setIconByPixmap(const QIcon &icon);
|
||||
|
||||
QString overlayIconName() const
|
||||
{ return mOverlayIconName; }
|
||||
void setOverlayIconByName(const QString &name);
|
||||
|
||||
IconPixmapList overlayIconPixmap() const
|
||||
{ return mOverlayIcon; }
|
||||
void setOverlayIconByPixmap(const QIcon &icon);
|
||||
|
||||
QString attentionIconName() const
|
||||
{ return mAttentionIconName; }
|
||||
void setAttentionIconByName(const QString &name);
|
||||
|
||||
IconPixmapList attentionIconPixmap() const
|
||||
{ return mAttentionIcon; }
|
||||
void setAttentionIconByPixmap(const QIcon &icon);
|
||||
|
||||
QString toolTipTitle() const
|
||||
{ return mTooltipTitle; }
|
||||
void setToolTipTitle(const QString &title);
|
||||
|
||||
QString toolTipSubTitle() const
|
||||
{ return mTooltipSubtitle; }
|
||||
void setToolTipSubTitle(const QString &subTitle);
|
||||
|
||||
QString toolTipIconName() const
|
||||
{ return mTooltipIconName; }
|
||||
void setToolTipIconByName(const QString &name);
|
||||
|
||||
IconPixmapList toolTipIconPixmap() const
|
||||
{ return mTooltipIcon; }
|
||||
void setToolTipIconByPixmap(const QIcon &icon);
|
||||
|
||||
ToolTip toolTip() const
|
||||
{
|
||||
ToolTip tt;
|
||||
tt.title = mTooltipTitle;
|
||||
tt.description = mTooltipSubtitle;
|
||||
tt.iconName = mTooltipIconName;
|
||||
tt.iconPixmap = mTooltipIcon;
|
||||
return tt;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \Note: we don't take ownership for the \param menu
|
||||
*/
|
||||
void setContextMenu(QMenu *menu);
|
||||
|
||||
public Q_SLOTS:
|
||||
void Activate(int x, int y);
|
||||
void SecondaryActivate(int x, int y);
|
||||
void ContextMenu(int x, int y);
|
||||
void Scroll(int delta, const QString &orientation);
|
||||
|
||||
void showMessage(const QString &title, const QString &msg, const QString &iconName, int secs);
|
||||
|
||||
private:
|
||||
void registerToHost();
|
||||
IconPixmapList iconToPixmapList(const QIcon &icon);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onServiceOwnerChanged(const QString &service, const QString &oldOwner,
|
||||
const QString &newOwner);
|
||||
void onMenuDestroyed();
|
||||
|
||||
Q_SIGNALS:
|
||||
void activateRequested(const QPoint &pos);
|
||||
void secondaryActivateRequested(const QPoint &pos);
|
||||
void scrollRequested(int delta, Qt::Orientation orientation);
|
||||
|
||||
private:
|
||||
StatusNotifierItemAdaptor *mAdaptor;
|
||||
|
||||
QString mService;
|
||||
QString mId;
|
||||
QString mTitle;
|
||||
QString mStatus;
|
||||
|
||||
// icons
|
||||
QString mIconName, mOverlayIconName, mAttentionIconName;
|
||||
IconPixmapList mIcon, mOverlayIcon, mAttentionIcon;
|
||||
qint64 mIconCacheKey, mOverlayIconCacheKey, mAttentionIconCacheKey;
|
||||
|
||||
// tooltip
|
||||
QString mTooltipTitle, mTooltipSubtitle, mTooltipIconName;
|
||||
IconPixmapList mTooltipIcon;
|
||||
qint64 mTooltipIconCacheKey;
|
||||
|
||||
// menu
|
||||
QMenu *mMenu;
|
||||
QDBusObjectPath mMenuPath;
|
||||
DBusMenuExporter *mMenuExporter;
|
||||
QDBusConnection mSessionBus;
|
||||
|
||||
static int mServiceCounter;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user