[kcmkwin/kwindecoration] Import a new decoration configuration module
Following features are supported: * finds all plugins ** finds all themes for a theme-engine plugin * renders previews for the plugin/themes * loads currently used plugin/theme * saves selected plugin/theme * triggers config reload in KWin Following features are currently not supported: * Search * Plugin configuration * GHNS * Button configuration
This commit is contained in:
parent
fcec334b3c
commit
8dd0a8163f
26 changed files with 2476 additions and 2285 deletions
|
@ -22,6 +22,7 @@ find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS
|
|||
Core
|
||||
DBus
|
||||
Quick
|
||||
QuickWidgets
|
||||
Script
|
||||
UiTools
|
||||
Widgets
|
||||
|
|
|
@ -1,23 +1,14 @@
|
|||
# KI18N Translation Domain for this library
|
||||
add_definitions(-DTRANSLATION_DOMAIN=\"kcmkwindecoration\")
|
||||
|
||||
# need a header file from Aurorae sources
|
||||
include_directories(
|
||||
${KWIN_SOURCE_DIR}/clients/aurorae/src/lib
|
||||
../utils/
|
||||
)
|
||||
|
||||
set(AURORAE_SOURCE_DIR ${KWIN_SOURCE_DIR}/clients/aurorae/src/lib/)
|
||||
add_subdirectory(declarative-plugin)
|
||||
|
||||
set(kcm_kwindecoration_PART_SRCS
|
||||
kwindecoration.cpp
|
||||
kcm.cpp
|
||||
buttons.cpp
|
||||
buttonsconfigdialog.cpp
|
||||
# buttonsconfigdialog.cpp
|
||||
configdialog.cpp
|
||||
preview.cpp
|
||||
decorationmodel.cpp
|
||||
${AURORAE_SOURCE_DIR}/auroraetheme.cpp
|
||||
${AURORAE_SOURCE_DIR}/themeconfig.cpp
|
||||
)
|
||||
|
||||
ki18n_wrap_ui(kcm_kwindecoration_PART_SRCS
|
||||
|
@ -29,14 +20,17 @@ ki18n_wrap_ui(kcm_kwindecoration_PART_SRCS
|
|||
|
||||
add_library(kcm_kwindecoration MODULE ${kcm_kwindecoration_PART_SRCS})
|
||||
target_link_libraries(kcm_kwindecoration
|
||||
kdecorations
|
||||
KDecoration2::KDecoration
|
||||
Qt5::DBus
|
||||
Qt5::Quick
|
||||
Qt5::QuickWidgets
|
||||
Qt5::UiTools
|
||||
KF5::Completion
|
||||
KF5::ConfigWidgets
|
||||
KF5::I18n
|
||||
KF5::NewStuff
|
||||
KF5::WindowSystem
|
||||
KF5::Service
|
||||
)
|
||||
install(TARGETS kcm_kwindecoration DESTINATION ${PLUGIN_INSTALL_DIR} )
|
||||
|
||||
|
@ -45,7 +39,4 @@ install(TARGETS kcm_kwindecoration DESTINATION ${PLUGIN_INSTALL_DIR} )
|
|||
install( FILES kwindecoration.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
|
||||
install( FILES
|
||||
qml/main.qml
|
||||
qml/AuroraeDecoration.qml
|
||||
qml/AuroraePreview.qml
|
||||
qml/DecorationPreview.qml
|
||||
DESTINATION ${DATA_INSTALL_DIR}/kwin/kcm_kwindecoration)
|
||||
|
|
20
kcmkwin/kwindecoration/declarative-plugin/CMakeLists.txt
Normal file
20
kcmkwin/kwindecoration/declarative-plugin/CMakeLists.txt
Normal file
|
@ -0,0 +1,20 @@
|
|||
set(plugin_SRCS
|
||||
previewbridge.cpp
|
||||
previewclient.cpp
|
||||
previewitem.cpp
|
||||
previewsettings.cpp
|
||||
plugin.cpp
|
||||
)
|
||||
|
||||
add_library(kdecorationprivatedeclarative SHARED ${plugin_SRCS})
|
||||
target_link_libraries(kdecorationprivatedeclarative
|
||||
KDecoration2::KDecoration
|
||||
KDecoration2::KDecoration2Private
|
||||
Qt5::Quick
|
||||
KF5::CoreAddons
|
||||
KF5::ConfigWidgets
|
||||
KF5::Service
|
||||
)
|
||||
|
||||
install(TARGETS kdecorationprivatedeclarative DESTINATION ${QML_INSTALL_DIR}/org/kde/kwin/private/kdecoration )
|
||||
install(FILES qmldir DESTINATION ${QML_INSTALL_DIR}/org/kde/kwin/private/kdecoration )
|
51
kcmkwin/kwindecoration/declarative-plugin/plugin.cpp
Normal file
51
kcmkwin/kwindecoration/declarative-plugin/plugin.cpp
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright 2014 Martin Gräßlin <mgraesslin@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "plugin.h"
|
||||
#include "previewbridge.h"
|
||||
#include "previewclient.h"
|
||||
#include "previewitem.h"
|
||||
#include "previewsettings.h"
|
||||
|
||||
#include <KDecoration2/Decoration>
|
||||
#include <KDecoration2/DecorationShadow>
|
||||
|
||||
#include <qqml.h>
|
||||
|
||||
namespace KDecoration2
|
||||
{
|
||||
namespace Preview
|
||||
{
|
||||
|
||||
void Plugin::registerTypes(const char *uri)
|
||||
{
|
||||
Q_ASSERT(QLatin1String(uri) == QLatin1String("org.kde.kwin.private.kdecoration"));
|
||||
qmlRegisterType<KDecoration2::Preview::PreviewBridge>(uri, 1, 0, "Bridge");
|
||||
qmlRegisterType<KDecoration2::Preview::Settings>(uri, 1, 0, "Settings");
|
||||
qmlRegisterType<KDecoration2::Preview::PreviewItem>(uri, 1, 0, "Decoration");
|
||||
qmlRegisterType<KDecoration2::Preview::PreviewClient>();
|
||||
qmlRegisterType<KDecoration2::Decoration>();
|
||||
qmlRegisterType<KDecoration2::DecorationShadow>();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#include "plugin.moc"
|
||||
|
41
kcmkwin/kwindecoration/declarative-plugin/plugin.h
Normal file
41
kcmkwin/kwindecoration/declarative-plugin/plugin.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright 2014 Martin Gräßlin <mgraesslin@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef KDECOARTIONS_PREVIEW_PLUGIN_H
|
||||
#define KDECOARTIONS_PREVIEW_PLUGIN_H
|
||||
|
||||
#include <QQmlExtensionPlugin>
|
||||
|
||||
namespace KDecoration2
|
||||
{
|
||||
namespace Preview
|
||||
{
|
||||
|
||||
class Plugin : public QQmlExtensionPlugin
|
||||
{
|
||||
Q_PLUGIN_METADATA(IID "org.kde.kdecoration2")
|
||||
Q_OBJECT
|
||||
public:
|
||||
void registerTypes(const char *uri) override;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
165
kcmkwin/kwindecoration/declarative-plugin/previewbridge.cpp
Normal file
165
kcmkwin/kwindecoration/declarative-plugin/previewbridge.cpp
Normal file
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
* Copyright 2014 Martin Gräßlin <mgraesslin@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "previewbridge.h"
|
||||
#include "previewclient.h"
|
||||
#include "previewitem.h"
|
||||
#include "previewsettings.h"
|
||||
|
||||
#include <KDecoration2/DecoratedClient>
|
||||
#include <KDecoration2/Decoration>
|
||||
|
||||
#include <KPluginLoader>
|
||||
#include <KPluginFactory>
|
||||
#include <KPluginTrader>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
namespace KDecoration2
|
||||
{
|
||||
namespace Preview
|
||||
{
|
||||
|
||||
static const QString s_pluginName = QStringLiteral("org.kde.kdecoration2");
|
||||
|
||||
PreviewBridge::PreviewBridge(QObject *parent)
|
||||
: DecorationBridge(parent)
|
||||
, m_lastCreatedClient(nullptr)
|
||||
, m_lastCreatedSettings(nullptr)
|
||||
, m_valid(false)
|
||||
{
|
||||
connect(this, &PreviewBridge::pluginChanged, this, &PreviewBridge::createFactory);
|
||||
}
|
||||
|
||||
PreviewBridge::~PreviewBridge() = default;
|
||||
|
||||
std::unique_ptr<DecoratedClientPrivate> PreviewBridge::createClient(DecoratedClient *client, Decoration *decoration)
|
||||
{
|
||||
auto ptr = std::unique_ptr<PreviewClient>(new PreviewClient(client, decoration));
|
||||
m_lastCreatedClient = ptr.get();
|
||||
return std::move(ptr);
|
||||
}
|
||||
|
||||
void PreviewBridge::update(Decoration *decoration, const QRect &geometry)
|
||||
{
|
||||
Q_UNUSED(geometry)
|
||||
auto it = std::find_if(m_previewItems.constBegin(), m_previewItems.constEnd(), [decoration](PreviewItem *item) {
|
||||
return item->decoration() == decoration;
|
||||
});
|
||||
if (it != m_previewItems.constEnd()) {
|
||||
(*it)->update();
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<DecorationSettingsPrivate> PreviewBridge::settings(DecorationSettings *parent)
|
||||
{
|
||||
auto ptr = std::unique_ptr<PreviewSettings>(new PreviewSettings(parent));
|
||||
m_lastCreatedSettings = ptr.get();
|
||||
return std::move(ptr);
|
||||
}
|
||||
|
||||
void PreviewBridge::registerPreviewItem(PreviewItem *item)
|
||||
{
|
||||
m_previewItems.append(item);
|
||||
}
|
||||
|
||||
void PreviewBridge::unregisterPreviewItem(PreviewItem *item)
|
||||
{
|
||||
m_previewItems.removeAll(item);
|
||||
}
|
||||
|
||||
void PreviewBridge::setPlugin(const QString &plugin)
|
||||
{
|
||||
if (m_plugin == plugin) {
|
||||
return;
|
||||
}
|
||||
m_plugin = plugin;
|
||||
qDebug() << "Plugin changed to: " << m_plugin;
|
||||
emit pluginChanged();
|
||||
}
|
||||
|
||||
QString PreviewBridge::theme() const
|
||||
{
|
||||
return m_theme;
|
||||
}
|
||||
|
||||
void PreviewBridge::setTheme(const QString &theme)
|
||||
{
|
||||
if (m_theme == theme) {
|
||||
return;
|
||||
}
|
||||
m_theme = theme;
|
||||
emit themeChanged();
|
||||
}
|
||||
|
||||
QString PreviewBridge::plugin() const
|
||||
{
|
||||
return m_plugin;
|
||||
}
|
||||
|
||||
void PreviewBridge::createFactory()
|
||||
{
|
||||
m_factory.clear();
|
||||
if (m_plugin.isNull()) {
|
||||
setValid(false);
|
||||
qDebug() <<"Plugin not set";
|
||||
return;
|
||||
}
|
||||
const auto offers = KPluginTrader::self()->query(s_pluginName,
|
||||
s_pluginName,
|
||||
QStringLiteral("[X-KDE-PluginInfo-Name] == '%1'").arg(m_plugin));
|
||||
if (offers.isEmpty()) {
|
||||
setValid(false);
|
||||
qDebug() << "no offers";
|
||||
return;
|
||||
}
|
||||
KPluginLoader loader(offers.first().libraryPath());
|
||||
m_factory = loader.factory();
|
||||
qDebug() << "Factory: " << !m_factory.isNull();
|
||||
setValid(!m_factory.isNull());
|
||||
}
|
||||
|
||||
bool PreviewBridge::isValid() const
|
||||
{
|
||||
return m_valid;
|
||||
}
|
||||
|
||||
void PreviewBridge::setValid(bool valid)
|
||||
{
|
||||
if (m_valid == valid) {
|
||||
return;
|
||||
}
|
||||
m_valid = valid;
|
||||
emit validChanged();
|
||||
}
|
||||
|
||||
Decoration *PreviewBridge::createDecoration(QObject *parent)
|
||||
{
|
||||
if (!m_valid) {
|
||||
return nullptr;
|
||||
}
|
||||
QVariantMap args({ {QStringLiteral("bridge"), QVariant::fromValue(this)} });
|
||||
if (!m_theme.isNull()) {
|
||||
args.insert(QStringLiteral("theme"), m_theme);
|
||||
}
|
||||
return m_factory->create<KDecoration2::Decoration>(parent, QVariantList({args}));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
92
kcmkwin/kwindecoration/declarative-plugin/previewbridge.h
Normal file
92
kcmkwin/kwindecoration/declarative-plugin/previewbridge.h
Normal file
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright 2014 Martin Gräßlin <mgraesslin@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef KDECOARTIONS_PREVIEW_BRIDGE_H
|
||||
#define KDECOARTIONS_PREVIEW_BRIDGE_H
|
||||
|
||||
#include <KDecoration2/Private/DecorationBridge>
|
||||
|
||||
#include <QList>
|
||||
#include <QPointer>
|
||||
|
||||
class KPluginFactory;
|
||||
|
||||
namespace KDecoration2
|
||||
{
|
||||
namespace Preview
|
||||
{
|
||||
|
||||
class PreviewClient;
|
||||
class PreviewItem;
|
||||
class PreviewSettings;
|
||||
|
||||
class PreviewBridge : public DecorationBridge
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString plugin READ plugin WRITE setPlugin NOTIFY pluginChanged)
|
||||
Q_PROPERTY(QString theme READ theme WRITE setTheme NOTIFY themeChanged)
|
||||
Q_PROPERTY(bool valid READ isValid NOTIFY validChanged)
|
||||
public:
|
||||
explicit PreviewBridge(QObject *parent = nullptr);
|
||||
virtual ~PreviewBridge();
|
||||
std::unique_ptr<DecoratedClientPrivate> createClient(DecoratedClient *client, Decoration *decoration) override;
|
||||
void update(Decoration* decoration, const QRect& geometry) override;
|
||||
std::unique_ptr<DecorationSettingsPrivate> settings(DecorationSettings *parent) override;
|
||||
|
||||
PreviewClient *lastCreatedClient() {
|
||||
return m_lastCreatedClient;
|
||||
}
|
||||
PreviewSettings *lastCreatedSettings() {
|
||||
return m_lastCreatedSettings;
|
||||
}
|
||||
|
||||
void registerPreviewItem(PreviewItem *item);
|
||||
void unregisterPreviewItem(PreviewItem *item);
|
||||
|
||||
void setPlugin(const QString &plugin);
|
||||
QString plugin() const;
|
||||
void setTheme(const QString &theme);
|
||||
QString theme() const;
|
||||
bool isValid() const;
|
||||
|
||||
KDecoration2::Decoration *createDecoration(QObject *parent = nullptr);
|
||||
|
||||
Q_SIGNALS:
|
||||
void pluginChanged();
|
||||
void themeChanged();
|
||||
void validChanged();
|
||||
|
||||
private:
|
||||
void createFactory();
|
||||
void setValid(bool valid);
|
||||
PreviewClient *m_lastCreatedClient;
|
||||
PreviewSettings *m_lastCreatedSettings;
|
||||
QList<PreviewItem*> m_previewItems;
|
||||
QString m_plugin;
|
||||
QString m_theme;
|
||||
QPointer<KPluginFactory> m_factory;
|
||||
bool m_valid;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(KDecoration2::Preview::PreviewBridge *)
|
||||
|
||||
#endif
|
463
kcmkwin/kwindecoration/declarative-plugin/previewclient.cpp
Normal file
463
kcmkwin/kwindecoration/declarative-plugin/previewclient.cpp
Normal file
|
@ -0,0 +1,463 @@
|
|||
/*
|
||||
* Copyright 2014 Martin Gräßlin <mgraesslin@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "previewclient.h"
|
||||
#include <KDecoration2/Decoration>
|
||||
#include <KDecoration2/DecoratedClient>
|
||||
|
||||
#include <KColorScheme>
|
||||
#include <KColorSchemeManager>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QModelIndex>
|
||||
|
||||
namespace KDecoration2
|
||||
{
|
||||
namespace Preview
|
||||
{
|
||||
|
||||
PreviewClient::PreviewClient(DecoratedClient *c, Decoration *decoration)
|
||||
: QObject(decoration)
|
||||
, DecoratedClientPrivate(c, decoration)
|
||||
, m_colorSchemeManager(new KColorSchemeManager(this))
|
||||
, m_colorSchemeIndex(0)
|
||||
, m_icon(QIcon::fromTheme(QStringLiteral("start-here-kde")))
|
||||
, m_iconName(m_icon.name())
|
||||
, m_active(true)
|
||||
, m_closeable(true)
|
||||
, m_keepBelow(false)
|
||||
, m_keepAbove(false)
|
||||
, m_maximizable(true)
|
||||
, m_maximizedHorizontally(false)
|
||||
, m_maximizedVertically(false)
|
||||
, m_minimizable(true)
|
||||
, m_modal(false)
|
||||
, m_movable(true)
|
||||
, m_resizable(true)
|
||||
, m_shadeable(true)
|
||||
, m_shaded(false)
|
||||
, m_providesContextHelp(false)
|
||||
, m_desktop(1)
|
||||
, m_width(0)
|
||||
, m_height(0)
|
||||
, m_bordersTopEdge(false)
|
||||
, m_bordersLeftEdge(false)
|
||||
, m_bordersRightEdge(false)
|
||||
, m_bordersBottomEdge(false)
|
||||
{
|
||||
connect(this, &PreviewClient::captionChanged, c, &DecoratedClient::captionChanged);
|
||||
connect(this, &PreviewClient::activeChanged, c, &DecoratedClient::activeChanged);
|
||||
connect(this, &PreviewClient::closeableChanged, c, &DecoratedClient::closeableChanged);
|
||||
connect(this, &PreviewClient::keepAboveChanged, c, &DecoratedClient::keepAboveChanged);
|
||||
connect(this, &PreviewClient::keepBelowChanged, c, &DecoratedClient::keepBelowChanged);
|
||||
connect(this, &PreviewClient::maximizableChanged, c, &DecoratedClient::maximizeableChanged);
|
||||
connect(this, &PreviewClient::maximizedChanged, c, &DecoratedClient::maximizedChanged);
|
||||
connect(this, &PreviewClient::maximizedVerticallyChanged, c, &DecoratedClient::maximizedVerticallyChanged);
|
||||
connect(this, &PreviewClient::maximizedHorizontallyChanged, c, &DecoratedClient::maximizedHorizontallyChanged);
|
||||
connect(this, &PreviewClient::minimizableChanged, c, &DecoratedClient::minimizeableChanged);
|
||||
// connect(this, &PreviewClient::modalChanged, c, &DecoratedClient::modalChanged);
|
||||
connect(this, &PreviewClient::movableChanged, c, &DecoratedClient::moveableChanged);
|
||||
connect(this, &PreviewClient::onAllDesktopsChanged, c, &DecoratedClient::onAllDesktopsChanged);
|
||||
connect(this, &PreviewClient::resizableChanged, c, &DecoratedClient::resizeableChanged);
|
||||
connect(this, &PreviewClient::shadeableChanged, c, &DecoratedClient::shadeableChanged);
|
||||
connect(this, &PreviewClient::shadedChanged, c, &DecoratedClient::shadedChanged);
|
||||
connect(this, &PreviewClient::providesContextHelpChanged, c, &DecoratedClient::providesContextHelpChanged);
|
||||
connect(this, &PreviewClient::onAllDesktopsChanged, c, &DecoratedClient::onAllDesktopsChanged);
|
||||
connect(this, &PreviewClient::widthChanged, c, &DecoratedClient::widthChanged);
|
||||
connect(this, &PreviewClient::heightChanged, c, &DecoratedClient::heightChanged);
|
||||
connect(this, &PreviewClient::iconChanged, c, &DecoratedClient::iconChanged);
|
||||
connect(this, &PreviewClient::paletteChanged, c, &DecoratedClient::paletteChanged);
|
||||
// connect(this, &PreviewClient::, c, &DecoratedClient::);
|
||||
connect(this, &PreviewClient::maximizedVerticallyChanged, this,
|
||||
[this]() {
|
||||
emit maximizedChanged(isMaximized());
|
||||
}
|
||||
);
|
||||
connect(this, &PreviewClient::maximizedHorizontallyChanged, this,
|
||||
[this]() {
|
||||
emit maximizedChanged(isMaximized());
|
||||
}
|
||||
);
|
||||
connect(this, &PreviewClient::iconNameChanged, this,
|
||||
[this]() {
|
||||
m_icon = QIcon::fromTheme(m_iconName);
|
||||
emit iconChanged(m_icon);
|
||||
}
|
||||
);
|
||||
connect(this, &PreviewClient::desktopChanged, this,
|
||||
[this]() {
|
||||
emit onAllDesktopsChanged(isOnAllDesktops());
|
||||
}
|
||||
);
|
||||
connect(this, &PreviewClient::colorSchemeIndexChanged, this,
|
||||
[this]() {
|
||||
const QModelIndex index = m_colorSchemeManager->model()->index(m_colorSchemeIndex, 0);
|
||||
qDebug() << "Scheme: " << index.data(Qt::UserRole).toString();
|
||||
m_palette = KColorScheme::createApplicationPalette(KSharedConfig::openConfig(index.data(Qt::UserRole).toString()));
|
||||
emit paletteChanged(m_palette);
|
||||
}
|
||||
);
|
||||
connect(decoration, &Decoration::titleBarDoubleClicked, this,
|
||||
[this]() {
|
||||
if (!isMaximizeable()) {
|
||||
return;
|
||||
}
|
||||
const bool maximize = !isMaximized();
|
||||
setMaximizedHorizontally(maximize);
|
||||
setMaximizedVertically(maximize);
|
||||
}
|
||||
);
|
||||
auto emitEdgesChanged = [this, c]() {
|
||||
c->borderingScreenEdgesChanged(borderingScreenEdges());
|
||||
};
|
||||
connect(this, &PreviewClient::bordersTopEdgeChanged, this, emitEdgesChanged);
|
||||
connect(this, &PreviewClient::bordersLeftEdgeChanged, this, emitEdgesChanged);
|
||||
connect(this, &PreviewClient::bordersRightEdgeChanged, this, emitEdgesChanged);
|
||||
connect(this, &PreviewClient::bordersBottomEdgeChanged, this, emitEdgesChanged);
|
||||
}
|
||||
|
||||
PreviewClient::~PreviewClient() = default;
|
||||
|
||||
void PreviewClient::setIcon(const QIcon &pixmap)
|
||||
{
|
||||
m_icon = pixmap;
|
||||
emit iconChanged(m_icon);
|
||||
}
|
||||
|
||||
int PreviewClient::width() const
|
||||
{
|
||||
return m_width;
|
||||
}
|
||||
|
||||
int PreviewClient::height() const
|
||||
{
|
||||
return m_height;
|
||||
}
|
||||
|
||||
QString PreviewClient::caption() const
|
||||
{
|
||||
return m_caption;
|
||||
}
|
||||
|
||||
WId PreviewClient::decorationId() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PreviewClient::desktop() const
|
||||
{
|
||||
return m_desktop;
|
||||
}
|
||||
|
||||
void PreviewClient::setDesktop(int desktop)
|
||||
{
|
||||
if (desktop == 0) {
|
||||
desktop = 1;
|
||||
}
|
||||
if (m_desktop == desktop) {
|
||||
return;
|
||||
}
|
||||
m_desktop = desktop;
|
||||
emit desktopChanged(m_desktop);
|
||||
}
|
||||
|
||||
QIcon PreviewClient::icon() const
|
||||
{
|
||||
return m_icon;
|
||||
}
|
||||
|
||||
QString PreviewClient::iconName() const
|
||||
{
|
||||
return m_iconName;
|
||||
}
|
||||
|
||||
bool PreviewClient::isActive() const
|
||||
{
|
||||
return m_active;
|
||||
}
|
||||
|
||||
bool PreviewClient::isCloseable() const
|
||||
{
|
||||
return m_closeable;
|
||||
}
|
||||
|
||||
bool PreviewClient::isKeepAbove() const
|
||||
{
|
||||
return m_keepAbove;
|
||||
}
|
||||
|
||||
bool PreviewClient::isKeepBelow() const
|
||||
{
|
||||
return m_keepBelow;
|
||||
}
|
||||
|
||||
bool PreviewClient::isMaximizeable() const
|
||||
{
|
||||
return m_maximizable;
|
||||
}
|
||||
|
||||
bool PreviewClient::isMaximized() const
|
||||
{
|
||||
return isMaximizedHorizontally() && isMaximizedVertically();
|
||||
}
|
||||
|
||||
bool PreviewClient::isMaximizedHorizontally() const
|
||||
{
|
||||
return m_maximizedHorizontally;
|
||||
}
|
||||
|
||||
bool PreviewClient::isMaximizedVertically() const
|
||||
{
|
||||
return m_maximizedVertically;
|
||||
}
|
||||
|
||||
bool PreviewClient::isMinimizeable() const
|
||||
{
|
||||
return m_minimizable;
|
||||
}
|
||||
|
||||
bool PreviewClient::isModal() const
|
||||
{
|
||||
return m_modal;
|
||||
}
|
||||
|
||||
bool PreviewClient::isMoveable() const
|
||||
{
|
||||
return m_movable;
|
||||
}
|
||||
|
||||
bool PreviewClient::isOnAllDesktops() const
|
||||
{
|
||||
return desktop() == -1;
|
||||
}
|
||||
|
||||
bool PreviewClient::isResizeable() const
|
||||
{
|
||||
return m_resizable;
|
||||
}
|
||||
|
||||
bool PreviewClient::isShadeable() const
|
||||
{
|
||||
return m_shadeable;
|
||||
}
|
||||
|
||||
bool PreviewClient::isShaded() const
|
||||
{
|
||||
return m_shaded;
|
||||
}
|
||||
|
||||
bool PreviewClient::providesContextHelp() const
|
||||
{
|
||||
return m_providesContextHelp;
|
||||
}
|
||||
|
||||
WId PreviewClient::windowId() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
QPalette PreviewClient::palette() const
|
||||
{
|
||||
return m_palette;
|
||||
}
|
||||
|
||||
QAbstractItemModel *PreviewClient::colorSchemeModel() const
|
||||
{
|
||||
return m_colorSchemeManager->model();
|
||||
}
|
||||
|
||||
int PreviewClient::colorSchemeIndex() const
|
||||
{
|
||||
return m_colorSchemeIndex;
|
||||
}
|
||||
|
||||
void PreviewClient::setColorSchemeIndex(int index)
|
||||
{
|
||||
if (m_colorSchemeIndex == index) {
|
||||
return;
|
||||
}
|
||||
m_colorSchemeIndex = index;
|
||||
emit colorSchemeIndexChanged(m_colorSchemeIndex);
|
||||
}
|
||||
|
||||
Qt::Edges PreviewClient::borderingScreenEdges() const
|
||||
{
|
||||
Qt::Edges edges;
|
||||
if (m_bordersBottomEdge) {
|
||||
edges |= Qt::BottomEdge;
|
||||
}
|
||||
if (m_bordersLeftEdge) {
|
||||
edges |= Qt::LeftEdge;
|
||||
}
|
||||
if (m_bordersRightEdge) {
|
||||
edges |= Qt::RightEdge;
|
||||
}
|
||||
if (m_bordersTopEdge) {
|
||||
edges |= Qt::TopEdge;
|
||||
}
|
||||
return edges;
|
||||
}
|
||||
|
||||
bool PreviewClient::bordersBottomEdge() const
|
||||
{
|
||||
return m_bordersBottomEdge;
|
||||
}
|
||||
|
||||
bool PreviewClient::bordersLeftEdge() const
|
||||
{
|
||||
return m_bordersLeftEdge;
|
||||
}
|
||||
|
||||
bool PreviewClient::bordersRightEdge() const
|
||||
{
|
||||
return m_bordersRightEdge;
|
||||
}
|
||||
|
||||
bool PreviewClient::bordersTopEdge() const
|
||||
{
|
||||
return m_bordersTopEdge;
|
||||
}
|
||||
|
||||
void PreviewClient::setBordersBottomEdge(bool enabled)
|
||||
{
|
||||
if (m_bordersBottomEdge == enabled) {
|
||||
return;
|
||||
}
|
||||
m_bordersBottomEdge = enabled;
|
||||
emit bordersBottomEdgeChanged(enabled);
|
||||
}
|
||||
|
||||
void PreviewClient::setBordersLeftEdge(bool enabled)
|
||||
{
|
||||
if (m_bordersLeftEdge == enabled) {
|
||||
return;
|
||||
}
|
||||
m_bordersLeftEdge = enabled;
|
||||
emit bordersLeftEdgeChanged(enabled);
|
||||
}
|
||||
|
||||
void PreviewClient::setBordersRightEdge(bool enabled)
|
||||
{
|
||||
if (m_bordersRightEdge == enabled) {
|
||||
return;
|
||||
}
|
||||
m_bordersRightEdge = enabled;
|
||||
emit bordersRightEdgeChanged(enabled);
|
||||
}
|
||||
|
||||
void PreviewClient::setBordersTopEdge(bool enabled)
|
||||
{
|
||||
if (m_bordersTopEdge == enabled) {
|
||||
return;
|
||||
}
|
||||
m_bordersTopEdge = enabled;
|
||||
emit bordersTopEdgeChanged(enabled);
|
||||
}
|
||||
|
||||
void PreviewClient::requestClose()
|
||||
{
|
||||
emit closeRequested();
|
||||
}
|
||||
|
||||
void PreviewClient::requestContextHelp()
|
||||
{
|
||||
qDebug() << "context help requested";
|
||||
}
|
||||
|
||||
void PreviewClient::requestMaximize(Qt::MouseButtons buttons)
|
||||
{
|
||||
if (buttons.testFlag(Qt::LeftButton)) {
|
||||
const bool set = !isMaximized();
|
||||
setMaximizedHorizontally(set);
|
||||
setMaximizedVertically(set);
|
||||
} else if (buttons.testFlag(Qt::RightButton)) {
|
||||
setMaximizedHorizontally(!isMaximizedHorizontally());
|
||||
} else if (buttons.testFlag(Qt::MiddleButton)) {
|
||||
setMaximizedVertically(!isMaximizedVertically());
|
||||
}
|
||||
}
|
||||
|
||||
void PreviewClient::requestMinimize()
|
||||
{
|
||||
emit minimizeRequested();
|
||||
}
|
||||
|
||||
void PreviewClient::requestToggleKeepAbove()
|
||||
{
|
||||
setKeepAbove(!isKeepAbove());
|
||||
}
|
||||
|
||||
void PreviewClient::requestToggleKeepBelow()
|
||||
{
|
||||
setKeepBelow(!isKeepBelow());
|
||||
}
|
||||
|
||||
void PreviewClient::requestShowWindowMenu()
|
||||
{
|
||||
emit showWindowMenuRequested();
|
||||
}
|
||||
|
||||
void PreviewClient::requestToggleOnAllDesktops()
|
||||
{
|
||||
setDesktop(isOnAllDesktops() ? 1 : -1);
|
||||
}
|
||||
|
||||
void PreviewClient::requestToggleShade()
|
||||
{
|
||||
setShaded(!isShaded());
|
||||
}
|
||||
|
||||
#define SETTER(type, name, variable) \
|
||||
void PreviewClient::name(type variable) \
|
||||
{ \
|
||||
if (m_##variable == variable) { \
|
||||
return; \
|
||||
} \
|
||||
qDebug() << "Setting " << #variable << ":" << variable;\
|
||||
m_##variable = variable; \
|
||||
emit variable##Changed(m_##variable); \
|
||||
}
|
||||
|
||||
#define SETTER2(name, variable) SETTER(bool, name, variable)
|
||||
|
||||
SETTER(const QString &, setCaption, caption)
|
||||
SETTER(const QString &, setIconName, iconName)
|
||||
SETTER(int, setWidth, width)
|
||||
SETTER(int, setHeight, height)
|
||||
|
||||
SETTER2(setActive, active)
|
||||
SETTER2(setCloseable, closeable)
|
||||
SETTER2(setMaximizable, maximizable)
|
||||
SETTER2(setKeepBelow, keepBelow)
|
||||
SETTER2(setKeepAbove, keepAbove)
|
||||
SETTER2(setMaximizedHorizontally, maximizedHorizontally)
|
||||
SETTER2(setMaximizedVertically, maximizedVertically)
|
||||
SETTER2(setMinimizable, minimizable)
|
||||
SETTER2(setModal, modal)
|
||||
SETTER2(setMovable, movable)
|
||||
SETTER2(setResizable, resizable)
|
||||
SETTER2(setShadeable, shadeable)
|
||||
SETTER2(setShaded, shaded)
|
||||
SETTER2(setProvidesContextHelp, providesContextHelp)
|
||||
|
||||
#undef SETTER2
|
||||
#undef SETTER
|
||||
|
||||
} // namespace Preview
|
||||
} // namespace KDecoration2
|
212
kcmkwin/kwindecoration/declarative-plugin/previewclient.h
Normal file
212
kcmkwin/kwindecoration/declarative-plugin/previewclient.h
Normal file
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
* Copyright 2014 Martin Gräßlin <mgraesslin@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef KDECOARTIONS_PREVIEW_CLIENT_H
|
||||
#define KDECOARTIONS_PREVIEW_CLIENT_H
|
||||
|
||||
#include <KDecoration2/Private/DecoratedClientPrivate>
|
||||
#include <QObject>
|
||||
#include <QPalette>
|
||||
|
||||
class KColorSchemeManager;
|
||||
class QAbstractItemModel;
|
||||
|
||||
namespace KDecoration2
|
||||
{
|
||||
namespace Preview
|
||||
{
|
||||
class PreviewClient : public QObject, public DecoratedClientPrivate
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(KDecoration2::Decoration *decoration READ decoration CONSTANT)
|
||||
Q_PROPERTY(QString caption READ caption WRITE setCaption NOTIFY captionChanged)
|
||||
Q_PROPERTY(QIcon icon READ icon WRITE setIcon NOTIFY iconChanged)
|
||||
Q_PROPERTY(QString iconName READ iconName WRITE setIconName NOTIFY iconNameChanged)
|
||||
Q_PROPERTY(QAbstractItemModel *colorSchemeModel READ colorSchemeModel CONSTANT)
|
||||
Q_PROPERTY(int colorSchemeIndex READ colorSchemeIndex WRITE setColorSchemeIndex NOTIFY colorSchemeIndexChanged)
|
||||
Q_PROPERTY(bool active READ isActive WRITE setActive NOTIFY activeChanged)
|
||||
Q_PROPERTY(bool closeable READ isCloseable WRITE setCloseable NOTIFY closeableChanged)
|
||||
Q_PROPERTY(bool keepAbove READ isKeepAbove WRITE setKeepAbove NOTIFY keepAboveChanged)
|
||||
Q_PROPERTY(bool keepBelow READ isKeepBelow WRITE setKeepBelow NOTIFY keepBelowChanged)
|
||||
Q_PROPERTY(bool maximizable READ isMaximizeable WRITE setMaximizable NOTIFY maximizableChanged)
|
||||
Q_PROPERTY(bool maximized READ isMaximized NOTIFY maximizedChanged)
|
||||
Q_PROPERTY(bool maximizedVertically READ isMaximizedVertically WRITE setMaximizedVertically NOTIFY maximizedVerticallyChanged)
|
||||
Q_PROPERTY(bool maximizedHorizontally READ isMaximizedHorizontally WRITE setMaximizedHorizontally NOTIFY maximizedHorizontallyChanged)
|
||||
Q_PROPERTY(bool minimizable READ isMinimizeable WRITE setMinimizable NOTIFY minimizableChanged)
|
||||
Q_PROPERTY(bool modal READ isModal WRITE setModal NOTIFY modalChanged)
|
||||
Q_PROPERTY(bool movable READ isMoveable WRITE setMovable NOTIFY movableChanged)
|
||||
Q_PROPERTY(int desktop READ desktop WRITE setDesktop NOTIFY desktopChanged)
|
||||
Q_PROPERTY(bool onAllDesktops READ isOnAllDesktops NOTIFY onAllDesktopsChanged)
|
||||
Q_PROPERTY(bool resizable READ isResizeable WRITE setResizable NOTIFY resizableChanged)
|
||||
Q_PROPERTY(bool shadeable READ isShadeable WRITE setShadeable NOTIFY shadeableChanged)
|
||||
Q_PROPERTY(bool shaded READ isShaded WRITE setShaded NOTIFY shadedChanged)
|
||||
Q_PROPERTY(bool providesContextHelp READ providesContextHelp WRITE setProvidesContextHelp NOTIFY providesContextHelpChanged)
|
||||
Q_PROPERTY(int width READ width WRITE setWidth NOTIFY widthChanged)
|
||||
Q_PROPERTY(int height READ height WRITE setHeight NOTIFY heightChanged)
|
||||
Q_PROPERTY(bool bordersTopEdge READ bordersTopEdge WRITE setBordersTopEdge NOTIFY bordersTopEdgeChanged)
|
||||
Q_PROPERTY(bool bordersLeftEdge READ bordersLeftEdge WRITE setBordersLeftEdge NOTIFY bordersLeftEdgeChanged)
|
||||
Q_PROPERTY(bool bordersRightEdge READ bordersRightEdge WRITE setBordersRightEdge NOTIFY bordersRightEdgeChanged)
|
||||
Q_PROPERTY(bool bordersBottomEdge READ bordersBottomEdge WRITE setBordersBottomEdge NOTIFY bordersBottomEdgeChanged)
|
||||
public:
|
||||
explicit PreviewClient(DecoratedClient *client, Decoration *decoration);
|
||||
virtual ~PreviewClient();
|
||||
|
||||
QString caption() const override;
|
||||
WId decorationId() const override;
|
||||
WId windowId() const override;
|
||||
int desktop() const override;
|
||||
QIcon icon() const override;
|
||||
bool isActive() const override;
|
||||
bool isCloseable() const override;
|
||||
bool isKeepAbove() const override;
|
||||
bool isKeepBelow() const override;
|
||||
bool isMaximizeable() const override;
|
||||
bool isMaximized() const override;
|
||||
bool isMaximizedVertically() const override;
|
||||
bool isMaximizedHorizontally() const override;
|
||||
bool isMinimizeable() const override;
|
||||
bool isModal() const override;
|
||||
bool isMoveable() const override;
|
||||
bool isOnAllDesktops() const override;
|
||||
bool isResizeable() const override;
|
||||
bool isShadeable() const override;
|
||||
bool isShaded() const override;
|
||||
bool providesContextHelp() const override;
|
||||
|
||||
int width() const override;
|
||||
int height() const override;
|
||||
QPalette palette() const override;
|
||||
Qt::Edges borderingScreenEdges() const override;
|
||||
|
||||
void requestClose() override;
|
||||
void requestContextHelp() override;
|
||||
void requestMaximize(Qt::MouseButtons buttons) override;
|
||||
void requestMinimize() override;
|
||||
void requestToggleKeepAbove() override;
|
||||
void requestToggleKeepBelow() override;
|
||||
void requestToggleShade() override;
|
||||
void requestShowWindowMenu() override;
|
||||
void requestToggleOnAllDesktops() override;
|
||||
|
||||
void setCaption(const QString &caption);
|
||||
void setActive(bool active);
|
||||
void setCloseable(bool closeable);
|
||||
void setMaximizable(bool maximizable);
|
||||
void setKeepBelow(bool keepBelow);
|
||||
void setKeepAbove(bool keepAbove);
|
||||
void setMaximizedHorizontally(bool maximized);
|
||||
void setMaximizedVertically(bool maximized);
|
||||
void setMinimizable(bool minimizable);
|
||||
void setModal(bool modal);
|
||||
void setMovable(bool movable);
|
||||
void setResizable(bool resizable);
|
||||
void setShadeable(bool shadeable);
|
||||
void setShaded(bool shaded);
|
||||
void setProvidesContextHelp(bool contextHelp);
|
||||
void setDesktop(int desktop);
|
||||
|
||||
void setWidth(int width);
|
||||
void setHeight(int height);
|
||||
|
||||
QString iconName() const;
|
||||
void setIconName(const QString &icon);
|
||||
void setIcon(const QIcon &icon);
|
||||
|
||||
QAbstractItemModel *colorSchemeModel() const;
|
||||
int colorSchemeIndex() const;
|
||||
void setColorSchemeIndex(int index);
|
||||
|
||||
bool bordersTopEdge() const;
|
||||
bool bordersLeftEdge() const;
|
||||
bool bordersRightEdge() const;
|
||||
bool bordersBottomEdge() const;
|
||||
|
||||
void setBordersTopEdge(bool enabled);
|
||||
void setBordersLeftEdge(bool enabled);
|
||||
void setBordersRightEdge(bool enabled);
|
||||
void setBordersBottomEdge(bool enabled);
|
||||
|
||||
Q_SIGNALS:
|
||||
void captionChanged(const QString &);
|
||||
void iconChanged(const QIcon &);
|
||||
void iconNameChanged(const QString &);
|
||||
void activeChanged(bool);
|
||||
void closeableChanged(bool);
|
||||
void keepAboveChanged(bool);
|
||||
void keepBelowChanged(bool);
|
||||
void maximizableChanged(bool);
|
||||
void maximizedChanged(bool);
|
||||
void maximizedVerticallyChanged(bool);
|
||||
void maximizedHorizontallyChanged(bool);
|
||||
void minimizableChanged(bool);
|
||||
void modalChanged(bool);
|
||||
void movableChanged(bool);
|
||||
void onAllDesktopsChanged(bool);
|
||||
void resizableChanged(bool);
|
||||
void shadeableChanged(bool);
|
||||
void shadedChanged(bool);
|
||||
void providesContextHelpChanged(bool);
|
||||
void desktopChanged(int);
|
||||
void widthChanged(int);
|
||||
void heightChanged(int);
|
||||
void colorSchemeIndexChanged(int);
|
||||
void paletteChanged(const QPalette&);
|
||||
void bordersTopEdgeChanged(bool);
|
||||
void bordersLeftEdgeChanged(bool);
|
||||
void bordersRightEdgeChanged(bool);
|
||||
void bordersBottomEdgeChanged(bool);
|
||||
|
||||
void showWindowMenuRequested();
|
||||
void minimizeRequested();
|
||||
void closeRequested();
|
||||
|
||||
private:
|
||||
KColorSchemeManager *m_colorSchemeManager;
|
||||
int m_colorSchemeIndex;
|
||||
QString m_caption;
|
||||
QIcon m_icon;
|
||||
QString m_iconName;
|
||||
QPalette m_palette;
|
||||
bool m_active;
|
||||
bool m_closeable;
|
||||
bool m_keepBelow;
|
||||
bool m_keepAbove;
|
||||
bool m_maximizable;
|
||||
bool m_maximizedHorizontally;
|
||||
bool m_maximizedVertically;
|
||||
bool m_minimizable;
|
||||
bool m_modal;
|
||||
bool m_movable;
|
||||
bool m_resizable;
|
||||
bool m_shadeable;
|
||||
bool m_shaded;
|
||||
bool m_providesContextHelp;
|
||||
int m_desktop;
|
||||
int m_width;
|
||||
int m_height;
|
||||
bool m_bordersTopEdge;
|
||||
bool m_bordersLeftEdge;
|
||||
bool m_bordersRightEdge;
|
||||
bool m_bordersBottomEdge;
|
||||
};
|
||||
|
||||
} // namespace Preview
|
||||
} // namespace KDecoration2
|
||||
|
||||
#endif
|
374
kcmkwin/kwindecoration/declarative-plugin/previewitem.cpp
Normal file
374
kcmkwin/kwindecoration/declarative-plugin/previewitem.cpp
Normal file
|
@ -0,0 +1,374 @@
|
|||
/*
|
||||
* Copyright 2014 Martin Gräßlin <mgraesslin@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "previewitem.h"
|
||||
#include "previewbridge.h"
|
||||
#include "previewsettings.h"
|
||||
#include "previewclient.h"
|
||||
#include <KDecoration2/Decoration>
|
||||
#include <KDecoration2/DecorationSettings>
|
||||
#include <KDecoration2/DecorationShadow>
|
||||
#include <KDecoration2/DecoratedClient>
|
||||
#include <QCursor>
|
||||
#include <QPainter>
|
||||
#include <QQmlContext>
|
||||
#include <QQmlEngine>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
namespace KDecoration2
|
||||
{
|
||||
namespace Preview
|
||||
{
|
||||
|
||||
PreviewItem::PreviewItem(QQuickItem *parent)
|
||||
: QQuickPaintedItem(parent)
|
||||
, m_decoration(nullptr)
|
||||
, m_windowColor(QPalette().background().color())
|
||||
{
|
||||
setAcceptHoverEvents(true);
|
||||
setFiltersChildMouseEvents(true);
|
||||
setAcceptedMouseButtons(Qt::MouseButtons(~Qt::NoButton));
|
||||
connect(this, &PreviewItem::widthChanged, this, &PreviewItem::syncSize);
|
||||
connect(this, &PreviewItem::heightChanged, this, &PreviewItem::syncSize);
|
||||
connect(this, &PreviewItem::bridgeChanged, this, &PreviewItem::createDecoration);
|
||||
connect(this, &PreviewItem::settingsChanged, this, &PreviewItem::createDecoration);
|
||||
}
|
||||
|
||||
PreviewItem::~PreviewItem()
|
||||
{
|
||||
if (m_bridge){
|
||||
m_bridge->unregisterPreviewItem(this);
|
||||
}
|
||||
}
|
||||
|
||||
void PreviewItem::componentComplete()
|
||||
{
|
||||
QQuickPaintedItem::componentComplete();
|
||||
createDecoration();
|
||||
if (m_decoration) {
|
||||
m_decoration->setSettings(m_settings->settings());
|
||||
m_decoration->init();
|
||||
syncSize();
|
||||
}
|
||||
}
|
||||
|
||||
void PreviewItem::createDecoration()
|
||||
{
|
||||
if (m_bridge.isNull() || m_settings.isNull() || m_decoration) {
|
||||
return;
|
||||
}
|
||||
m_decoration = m_bridge->createDecoration(this);
|
||||
if (!m_decoration) {
|
||||
return;
|
||||
}
|
||||
m_decoration->setProperty("visualParent", QVariant::fromValue(this));
|
||||
m_client = m_bridge->lastCreatedClient();
|
||||
connect(m_decoration, &Decoration::bordersChanged, this, &PreviewItem::syncSize);
|
||||
connect(m_decoration, &Decoration::shadowChanged, this, &PreviewItem::syncSize);
|
||||
emit decorationChanged(m_decoration);
|
||||
}
|
||||
|
||||
Decoration *PreviewItem::decoration() const
|
||||
{
|
||||
return m_decoration;
|
||||
}
|
||||
|
||||
void PreviewItem::setDecoration(Decoration *deco)
|
||||
{
|
||||
if (m_decoration == deco) {
|
||||
return;
|
||||
}
|
||||
auto updateSlot = static_cast<void (QQuickItem::*)()>(&QQuickItem::update);
|
||||
if (m_decoration) {
|
||||
disconnect(m_decoration, &Decoration::bordersChanged, this, updateSlot);
|
||||
}
|
||||
m_decoration = deco;
|
||||
m_decoration->setProperty("visualParent", QVariant::fromValue(this));
|
||||
connect(m_decoration, &Decoration::bordersChanged, this, updateSlot);
|
||||
connect(m_decoration, &Decoration::windowFrameSectionChanged, this,
|
||||
[this](Qt::WindowFrameSection section) {
|
||||
switch (section) {
|
||||
case Qt::TopRightSection:
|
||||
case Qt::BottomLeftSection:
|
||||
setCursor(Qt::SizeBDiagCursor);
|
||||
return;
|
||||
case Qt::TopLeftSection:
|
||||
case Qt::BottomRightSection:
|
||||
setCursor(Qt::SizeFDiagCursor);
|
||||
return;
|
||||
case Qt::TopSection:
|
||||
case Qt::BottomSection:
|
||||
setCursor(Qt::SizeVerCursor);
|
||||
return;
|
||||
case Qt::LeftSection:
|
||||
case Qt::RightSection:
|
||||
setCursor(Qt::SizeHorCursor);
|
||||
return;
|
||||
default:
|
||||
setCursor(Qt::ArrowCursor);
|
||||
}
|
||||
}
|
||||
);
|
||||
emit decorationChanged(m_decoration);
|
||||
}
|
||||
|
||||
QColor PreviewItem::windowColor() const
|
||||
{
|
||||
return m_windowColor;
|
||||
}
|
||||
|
||||
void PreviewItem::setWindowColor(const QColor &color)
|
||||
{
|
||||
if (m_windowColor == color) {
|
||||
return;
|
||||
}
|
||||
m_windowColor = color;
|
||||
emit windowColorChanged(m_windowColor);
|
||||
update();
|
||||
}
|
||||
|
||||
void PreviewItem::paint(QPainter *painter)
|
||||
{
|
||||
if (!m_decoration) {
|
||||
return;
|
||||
}
|
||||
int paddingLeft = 0;
|
||||
int paddingTop = 0;
|
||||
int paddingRight = 0;
|
||||
int paddingBottom = 0;
|
||||
paintShadow(painter, paddingLeft, paddingRight, paddingTop, paddingBottom);
|
||||
m_decoration->paint(painter);
|
||||
if (m_drawBackground) {
|
||||
painter->fillRect(m_decoration->borderLeft(), m_decoration->borderTop(),
|
||||
width() - m_decoration->borderLeft() - m_decoration->borderRight() - paddingLeft - paddingRight,
|
||||
height() - m_decoration->borderTop() - m_decoration->borderBottom() - paddingTop - paddingBottom,
|
||||
m_windowColor);
|
||||
}
|
||||
}
|
||||
|
||||
void PreviewItem::paintShadow(QPainter *painter, int &paddingLeft, int &paddingRight, int &paddingTop, int &paddingBottom)
|
||||
{
|
||||
const DecorationShadow *shadow = ((const Decoration*)(m_decoration))->shadow();
|
||||
if (!shadow) {
|
||||
return;
|
||||
}
|
||||
paddingLeft = shadow->paddingLeft();
|
||||
paddingTop = shadow->paddingTop();
|
||||
paddingRight = shadow->paddingRight();
|
||||
paddingBottom = shadow->paddingBottom();
|
||||
const QImage img = shadow->shadow();
|
||||
if (img.isNull()) {
|
||||
return;
|
||||
}
|
||||
const QRect topLeft = QRect(QPoint(0, 0), shadow->topLeft());
|
||||
const QRect top = QRect(QPoint(topLeft.width(), 0), shadow->top());
|
||||
const QRect topRight = QRect(QPoint(topLeft.width() + top.width(), 0), shadow->topRight());
|
||||
const QRect right = QRect(QPoint(topLeft.width() + top.width(), topRight.height()), shadow->right());
|
||||
const QRect left = QRect(QPoint(0, topLeft.height()), shadow->left());
|
||||
const QRect bottomLeft = QRect(QPoint(0, topLeft.height() + left.height()), shadow->bottomLeft());
|
||||
const QRect bottom = QRect(QPoint(bottomLeft.width(), img.height() - shadow->bottom().height()), shadow->bottom());
|
||||
const QRect bottomRight = QRect(QPoint(bottomLeft.width() + bottom.width(), topRight.height() + right.height()), shadow->bottomRight());
|
||||
|
||||
painter->translate(paddingLeft, paddingTop);
|
||||
|
||||
// top left
|
||||
painter->drawImage(QPoint(-paddingLeft, -paddingTop), img, topLeft);
|
||||
// top
|
||||
painter->drawImage(QRect(-paddingLeft + topLeft.width(), -paddingTop, width() - topLeft.width() - topRight.width(), top.height()), img, top);
|
||||
// top right
|
||||
painter->drawImage(QPoint(width() - topRight.width() - paddingLeft, -paddingTop), img, topRight);
|
||||
// right
|
||||
painter->drawImage(QRect(width() - right.width() - paddingLeft, -paddingTop + topRight.height(), right.width(), height() - topRight.height() - bottomRight.height()), img, right);
|
||||
// bottom right
|
||||
painter->drawImage(QPoint(width() - paddingLeft - bottomRight.width(), height() - paddingTop - bottomRight.height()), img, bottomRight);
|
||||
// bottom
|
||||
painter->drawImage(QRect(-paddingLeft + bottomLeft.width(), height() - bottom.height() - paddingTop, width() - bottomLeft.width() - bottomRight.width(), bottom.height()), img, bottom);
|
||||
// bottom left
|
||||
painter->drawImage(QPoint(-paddingLeft, height() - bottomLeft.height() - paddingTop), img, bottomLeft);
|
||||
// left
|
||||
painter->drawImage(QRect(-paddingLeft, -paddingTop + topLeft.height(), left.width(), height() - topLeft.height() - bottomLeft.height()), img, left);
|
||||
}
|
||||
|
||||
void PreviewItem::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
{
|
||||
if (const DecorationShadow *shadow = ((const Decoration*)(m_decoration))->shadow()) {
|
||||
QMouseEvent e(event->type(),
|
||||
event->localPos() - QPointF(shadow->paddingLeft(), shadow->paddingTop()),
|
||||
event->button(),
|
||||
event->buttons(),
|
||||
event->modifiers());
|
||||
QCoreApplication::instance()->sendEvent(decoration(), &e);
|
||||
} else {
|
||||
QCoreApplication::instance()->sendEvent(decoration(), event);
|
||||
}
|
||||
}
|
||||
|
||||
void PreviewItem::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (const DecorationShadow *shadow = ((const Decoration*)(m_decoration))->shadow()) {
|
||||
QMouseEvent e(event->type(),
|
||||
event->localPos() - QPointF(shadow->paddingLeft(), shadow->paddingTop()),
|
||||
event->button(),
|
||||
event->buttons(),
|
||||
event->modifiers());
|
||||
QCoreApplication::instance()->sendEvent(decoration(), &e);
|
||||
} else {
|
||||
QCoreApplication::instance()->sendEvent(decoration(), event);
|
||||
}
|
||||
}
|
||||
|
||||
void PreviewItem::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
if (const DecorationShadow *shadow = ((const Decoration*)(m_decoration))->shadow()) {
|
||||
QMouseEvent e(event->type(),
|
||||
event->localPos() - QPointF(shadow->paddingLeft(), shadow->paddingTop()),
|
||||
event->button(),
|
||||
event->buttons(),
|
||||
event->modifiers());
|
||||
QCoreApplication::instance()->sendEvent(decoration(), &e);
|
||||
} else {
|
||||
QCoreApplication::instance()->sendEvent(decoration(), event);
|
||||
}
|
||||
}
|
||||
|
||||
void PreviewItem::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
if (const DecorationShadow *shadow = ((const Decoration*)(m_decoration))->shadow()) {
|
||||
QMouseEvent e(event->type(),
|
||||
event->localPos() - QPointF(shadow->paddingLeft(), shadow->paddingTop()),
|
||||
event->button(),
|
||||
event->buttons(),
|
||||
event->modifiers());
|
||||
QCoreApplication::instance()->sendEvent(decoration(), &e);
|
||||
} else {
|
||||
QCoreApplication::instance()->sendEvent(decoration(), event);
|
||||
}
|
||||
}
|
||||
|
||||
void PreviewItem::hoverEnterEvent(QHoverEvent *event)
|
||||
{
|
||||
if (const DecorationShadow *shadow = ((const Decoration*)(m_decoration))->shadow()) {
|
||||
QHoverEvent e(event->type(),
|
||||
event->posF() - QPointF(shadow->paddingLeft(), shadow->paddingTop()),
|
||||
event->oldPosF() - QPointF(shadow->paddingLeft(), shadow->paddingTop()),
|
||||
event->modifiers());
|
||||
QCoreApplication::instance()->sendEvent(decoration(), &e);
|
||||
} else {
|
||||
QCoreApplication::instance()->sendEvent(decoration(), event);
|
||||
}
|
||||
}
|
||||
|
||||
void PreviewItem::hoverLeaveEvent(QHoverEvent *event)
|
||||
{
|
||||
if (const DecorationShadow *shadow = ((const Decoration*)(m_decoration))->shadow()) {
|
||||
QHoverEvent e(event->type(),
|
||||
event->posF() - QPointF(shadow->paddingLeft(), shadow->paddingTop()),
|
||||
event->oldPosF() - QPointF(shadow->paddingLeft(), shadow->paddingTop()),
|
||||
event->modifiers());
|
||||
QCoreApplication::instance()->sendEvent(decoration(), &e);
|
||||
} else {
|
||||
QCoreApplication::instance()->sendEvent(decoration(), event);
|
||||
}
|
||||
}
|
||||
|
||||
void PreviewItem::hoverMoveEvent(QHoverEvent *event)
|
||||
{
|
||||
if (const DecorationShadow *shadow = ((const Decoration*)(m_decoration))->shadow()) {
|
||||
QHoverEvent e(event->type(),
|
||||
event->posF() - QPointF(shadow->paddingLeft(), shadow->paddingTop()),
|
||||
event->oldPosF() - QPointF(shadow->paddingLeft(), shadow->paddingTop()),
|
||||
event->modifiers());
|
||||
QCoreApplication::instance()->sendEvent(decoration(), &e);
|
||||
} else {
|
||||
QCoreApplication::instance()->sendEvent(decoration(), event);
|
||||
}
|
||||
}
|
||||
|
||||
bool PreviewItem::isDrawingBackground() const
|
||||
{
|
||||
return m_drawBackground;
|
||||
}
|
||||
|
||||
void PreviewItem::setDrawingBackground(bool set)
|
||||
{
|
||||
if (m_drawBackground == set) {
|
||||
return;
|
||||
}
|
||||
m_drawBackground = set;
|
||||
emit drawingBackgroundChanged(set);
|
||||
}
|
||||
|
||||
PreviewBridge *PreviewItem::bridge() const
|
||||
{
|
||||
return m_bridge.data();
|
||||
}
|
||||
|
||||
void PreviewItem::setBridge(PreviewBridge *bridge)
|
||||
{
|
||||
if (m_bridge == bridge) {
|
||||
return;
|
||||
}
|
||||
if (m_bridge) {
|
||||
m_bridge->unregisterPreviewItem(this);
|
||||
}
|
||||
m_bridge = bridge;
|
||||
if (m_bridge) {
|
||||
m_bridge->registerPreviewItem(this);
|
||||
}
|
||||
emit bridgeChanged();
|
||||
}
|
||||
|
||||
Settings *PreviewItem::settings() const
|
||||
{
|
||||
return m_settings.data();
|
||||
}
|
||||
|
||||
void PreviewItem::setSettings(Settings *settings)
|
||||
{
|
||||
if (m_settings == settings) {
|
||||
return;
|
||||
}
|
||||
m_settings = settings;
|
||||
emit settingsChanged();
|
||||
}
|
||||
|
||||
PreviewClient *PreviewItem::client()
|
||||
{
|
||||
return m_client.data();
|
||||
}
|
||||
|
||||
void PreviewItem::syncSize()
|
||||
{
|
||||
if (!m_client) {
|
||||
return;
|
||||
}
|
||||
int widthOffset = 0;
|
||||
int heightOffset = 0;
|
||||
auto shadow = m_decoration->shadow();
|
||||
if (shadow) {
|
||||
widthOffset = shadow->paddingLeft() + shadow->paddingRight();
|
||||
heightOffset = shadow->paddingTop() + shadow->paddingBottom();
|
||||
}
|
||||
m_client->setWidth(width() - m_decoration->borderLeft() - m_decoration->borderRight() - widthOffset);
|
||||
m_client->setHeight(height() - m_decoration->borderTop() - m_decoration->borderBottom() - heightOffset);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
100
kcmkwin/kwindecoration/declarative-plugin/previewitem.h
Normal file
100
kcmkwin/kwindecoration/declarative-plugin/previewitem.h
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright 2014 Martin Gräßlin <mgraesslin@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef KDECOARTIONS_PREVIEW_ITEM_H
|
||||
#define KDECOARTIONS_PREVIEW_ITEM_H
|
||||
|
||||
#include <QQuickPaintedItem>
|
||||
#include <QPointer>
|
||||
|
||||
namespace KDecoration2
|
||||
{
|
||||
class Decoration;
|
||||
class DecorationSettings;
|
||||
|
||||
namespace Preview
|
||||
{
|
||||
class PreviewBridge;
|
||||
class PreviewClient;
|
||||
class Settings;
|
||||
|
||||
class PreviewItem : public QQuickPaintedItem
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(KDecoration2::Decoration *decoration READ decoration NOTIFY decorationChanged)
|
||||
Q_PROPERTY(KDecoration2::Preview::PreviewBridge *bridge READ bridge WRITE setBridge NOTIFY bridgeChanged)
|
||||
Q_PROPERTY(KDecoration2::Preview::Settings *settings READ settings WRITE setSettings NOTIFY settingsChanged)
|
||||
Q_PROPERTY(KDecoration2::Preview::PreviewClient *client READ client)
|
||||
Q_PROPERTY(QColor windowColor READ windowColor WRITE setWindowColor NOTIFY windowColorChanged)
|
||||
Q_PROPERTY(bool drawBackground READ isDrawingBackground WRITE setDrawingBackground NOTIFY drawingBackgroundChanged)
|
||||
public:
|
||||
PreviewItem(QQuickItem *parent = nullptr);
|
||||
virtual ~PreviewItem();
|
||||
void paint(QPainter *painter);
|
||||
|
||||
KDecoration2::Decoration *decoration() const;
|
||||
void setDecoration(KDecoration2::Decoration *deco);
|
||||
|
||||
QColor windowColor() const;
|
||||
void setWindowColor(const QColor &color);
|
||||
|
||||
bool isDrawingBackground() const;
|
||||
void setDrawingBackground(bool set);
|
||||
|
||||
PreviewBridge *bridge() const;
|
||||
void setBridge(PreviewBridge *bridge);
|
||||
|
||||
Settings *settings() const;
|
||||
void setSettings(Settings *settings);
|
||||
|
||||
PreviewClient *client();
|
||||
|
||||
Q_SIGNALS:
|
||||
void decorationChanged(KDecoration2::Decoration *deco);
|
||||
void windowColorChanged(const QColor &color);
|
||||
void drawingBackgroundChanged(bool);
|
||||
void bridgeChanged();
|
||||
void settingsChanged();
|
||||
|
||||
protected:
|
||||
void mouseDoubleClickEvent(QMouseEvent *event) override;
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
void hoverEnterEvent(QHoverEvent *event) override;
|
||||
void hoverLeaveEvent(QHoverEvent *event) override;
|
||||
void hoverMoveEvent(QHoverEvent *event) override;
|
||||
void componentComplete() override;
|
||||
|
||||
private:
|
||||
void paintShadow(QPainter *painter, int &paddingLeft, int &paddingRight, int &paddingTop, int &paddingBottom);
|
||||
void syncSize();
|
||||
void createDecoration();
|
||||
Decoration *m_decoration;
|
||||
QColor m_windowColor;
|
||||
bool m_drawBackground = true;
|
||||
QPointer<KDecoration2::Preview::PreviewBridge> m_bridge;
|
||||
QPointer<KDecoration2::Preview::Settings> m_settings;
|
||||
QPointer<KDecoration2::Preview::PreviewClient> m_client;
|
||||
};
|
||||
|
||||
} // Preview
|
||||
} // KDecoration2
|
||||
|
||||
#endif
|
325
kcmkwin/kwindecoration/declarative-plugin/previewsettings.cpp
Normal file
325
kcmkwin/kwindecoration/declarative-plugin/previewsettings.cpp
Normal file
|
@ -0,0 +1,325 @@
|
|||
/*
|
||||
* Copyright 2014 Martin Gräßlin <mgraesslin@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "previewsettings.h"
|
||||
#include "previewbridge.h"
|
||||
|
||||
#include <QFontDatabase>
|
||||
|
||||
namespace KDecoration2
|
||||
{
|
||||
|
||||
namespace Preview
|
||||
{
|
||||
|
||||
ButtonsModel::ButtonsModel(const QList< DecorationButtonType > &buttons, QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
, m_buttons(buttons)
|
||||
{
|
||||
}
|
||||
|
||||
ButtonsModel::~ButtonsModel() = default;
|
||||
|
||||
int ButtonsModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (parent.isValid()) {
|
||||
return 0;
|
||||
}
|
||||
return m_buttons.count();
|
||||
}
|
||||
|
||||
QVariant ButtonsModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid() ||
|
||||
index.row() < 0 ||
|
||||
index.row() >= m_buttons.count() ||
|
||||
index.column() != 0) {
|
||||
return QVariant();
|
||||
}
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
return QVariant::fromValue(m_buttons.at(index.row()));
|
||||
case Qt::UserRole:
|
||||
return QVariant::fromValue(m_buttons.at(index.row()));
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QHash< int, QByteArray > ButtonsModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
roles.insert(Qt::DisplayRole, QByteArrayLiteral("display"));
|
||||
return roles;
|
||||
}
|
||||
|
||||
void ButtonsModel::remove(int row)
|
||||
{
|
||||
if (row < 0 || row >= m_buttons.count()) {
|
||||
return;
|
||||
}
|
||||
beginRemoveRows(QModelIndex(), row, row);
|
||||
m_buttons.removeAt(row);
|
||||
endRemoveRows();
|
||||
}
|
||||
|
||||
void ButtonsModel::down(int index)
|
||||
{
|
||||
if (m_buttons.count() < 2 || index == m_buttons.count() -1) {
|
||||
return;
|
||||
}
|
||||
beginMoveRows(QModelIndex(), index, index, QModelIndex(), index + 2);
|
||||
m_buttons.move(index, index + 1);
|
||||
endMoveRows();
|
||||
}
|
||||
|
||||
void ButtonsModel::up(int index)
|
||||
{
|
||||
if (m_buttons.count() < 2 || index == 0) {
|
||||
return;
|
||||
}
|
||||
beginMoveRows(QModelIndex(), index, index, QModelIndex(), index -1);
|
||||
m_buttons.move(index, index - 1);
|
||||
endMoveRows();
|
||||
}
|
||||
|
||||
void ButtonsModel::add(DecorationButtonType type)
|
||||
{
|
||||
beginInsertRows(QModelIndex(), m_buttons.count(), m_buttons.count());
|
||||
m_buttons.append(type);
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
BorderSizesModel::BorderSizesModel(QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
BorderSizesModel::~BorderSizesModel() = default;
|
||||
|
||||
QVariant BorderSizesModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= m_borders.count() || index.column() != 0) {
|
||||
return QVariant();
|
||||
}
|
||||
if (role != Qt::DisplayRole && role != Qt::UserRole) {
|
||||
return QVariant();
|
||||
}
|
||||
return QVariant::fromValue<BorderSize>(m_borders.at(index.row()));
|
||||
}
|
||||
|
||||
int BorderSizesModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (parent.isValid()) {
|
||||
return 0;
|
||||
}
|
||||
return m_borders.count();
|
||||
}
|
||||
|
||||
QHash< int, QByteArray > BorderSizesModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
roles.insert(Qt::DisplayRole, QByteArrayLiteral("display"));
|
||||
return roles;
|
||||
}
|
||||
|
||||
PreviewSettings::PreviewSettings(DecorationSettings *parent)
|
||||
: QObject()
|
||||
, DecorationSettingsPrivate(parent)
|
||||
, m_alphaChannelSupported(true)
|
||||
, m_onAllDesktopsAvailable(true)
|
||||
, m_closeOnDoubleClick(false)
|
||||
, m_leftButtons(new ButtonsModel(QList<DecorationButtonType>({
|
||||
DecorationButtonType::Menu,
|
||||
DecorationButtonType::OnAllDesktops
|
||||
}), this))
|
||||
, m_rightButtons(new ButtonsModel(QList<DecorationButtonType>({
|
||||
DecorationButtonType::QuickHelp,
|
||||
DecorationButtonType::Minimize,
|
||||
DecorationButtonType::Maximize,
|
||||
DecorationButtonType::Close
|
||||
}), this))
|
||||
, m_availableButtons(new ButtonsModel(QList<DecorationButtonType>({
|
||||
DecorationButtonType::Menu,
|
||||
DecorationButtonType::ApplicationMenu,
|
||||
DecorationButtonType::OnAllDesktops,
|
||||
DecorationButtonType::Minimize,
|
||||
DecorationButtonType::Maximize,
|
||||
DecorationButtonType::Close,
|
||||
DecorationButtonType::QuickHelp,
|
||||
DecorationButtonType::Shade,
|
||||
DecorationButtonType::KeepBelow,
|
||||
DecorationButtonType::KeepAbove
|
||||
}), this))
|
||||
, m_borderSizes(new BorderSizesModel(this))
|
||||
, m_borderSize(int(BorderSize::Normal))
|
||||
, m_font(QFontDatabase::systemFont(QFontDatabase::TitleFont))
|
||||
{
|
||||
connect(this, &PreviewSettings::alphaChannelSupportedChanged, parent, &DecorationSettings::alphaChannelSupportedChanged);
|
||||
connect(this, &PreviewSettings::onAllDesktopsAvailableChanged, parent, &DecorationSettings::onAllDesktopsAvailableChanged);
|
||||
connect(this, &PreviewSettings::closeOnDoubleClickOnMenuChanged, parent, &DecorationSettings::closeOnDoubleClickOnMenuChanged);
|
||||
connect(this, &PreviewSettings::fontChanged, parent, &DecorationSettings::fontChanged);
|
||||
auto updateLeft = [this, parent]() {
|
||||
parent->decorationButtonsLeftChanged(decorationButtonsLeft());
|
||||
};
|
||||
auto updateRight = [this, parent]() {
|
||||
parent->decorationButtonsRightChanged(decorationButtonsRight());
|
||||
};
|
||||
connect(m_leftButtons, &QAbstractItemModel::rowsRemoved, this, updateLeft);
|
||||
connect(m_leftButtons, &QAbstractItemModel::rowsMoved, this, updateLeft);
|
||||
connect(m_leftButtons, &QAbstractItemModel::rowsInserted, this, updateLeft);
|
||||
connect(m_rightButtons, &QAbstractItemModel::rowsRemoved, this, updateRight);
|
||||
connect(m_rightButtons, &QAbstractItemModel::rowsMoved, this, updateRight);
|
||||
connect(m_rightButtons, &QAbstractItemModel::rowsInserted, this, updateRight);
|
||||
}
|
||||
|
||||
PreviewSettings::~PreviewSettings() = default;
|
||||
|
||||
bool PreviewSettings::isAlphaChannelSupported() const
|
||||
{
|
||||
return m_alphaChannelSupported;
|
||||
}
|
||||
|
||||
bool PreviewSettings::isOnAllDesktopsAvailable() const
|
||||
{
|
||||
return m_onAllDesktopsAvailable;
|
||||
}
|
||||
|
||||
void PreviewSettings::setAlphaChannelSupported(bool supported)
|
||||
{
|
||||
if (m_alphaChannelSupported == supported) {
|
||||
return;
|
||||
}
|
||||
m_alphaChannelSupported = supported;
|
||||
emit alphaChannelSupportedChanged(m_alphaChannelSupported);
|
||||
}
|
||||
|
||||
void PreviewSettings::setOnAllDesktopsAvailable(bool available)
|
||||
{
|
||||
if (m_onAllDesktopsAvailable == available) {
|
||||
return;
|
||||
}
|
||||
m_onAllDesktopsAvailable = available;
|
||||
emit onAllDesktopsAvailableChanged(m_onAllDesktopsAvailable);
|
||||
}
|
||||
|
||||
void PreviewSettings::setCloseOnDoubleClickOnMenu(bool enabled)
|
||||
{
|
||||
if (m_closeOnDoubleClick == enabled) {
|
||||
return;
|
||||
}
|
||||
m_closeOnDoubleClick = enabled;
|
||||
emit closeOnDoubleClickOnMenuChanged(enabled);
|
||||
}
|
||||
|
||||
QList< DecorationButtonType > PreviewSettings::decorationButtonsLeft() const
|
||||
{
|
||||
return m_leftButtons->buttons();
|
||||
}
|
||||
|
||||
QList< DecorationButtonType > PreviewSettings::decorationButtonsRight() const
|
||||
{
|
||||
return m_rightButtons->buttons();
|
||||
}
|
||||
|
||||
void PreviewSettings::addButtonToLeft(int row)
|
||||
{
|
||||
QModelIndex index = m_availableButtons->index(row);
|
||||
if (!index.isValid()) {
|
||||
return;
|
||||
}
|
||||
m_leftButtons->add(index.data(Qt::UserRole).value<DecorationButtonType>());
|
||||
}
|
||||
|
||||
void PreviewSettings::addButtonToRight(int row)
|
||||
{
|
||||
QModelIndex index = m_availableButtons->index(row);
|
||||
if (!index.isValid()) {
|
||||
return;
|
||||
}
|
||||
m_rightButtons->add(index.data(Qt::UserRole).value<DecorationButtonType>());
|
||||
}
|
||||
|
||||
void PreviewSettings::setBorderSizesIndex(int index)
|
||||
{
|
||||
if (m_borderSize == index) {
|
||||
return;
|
||||
}
|
||||
m_borderSize = index;
|
||||
emit borderSizesIndexChanged(index);
|
||||
emit decorationSettings()->borderSizeChanged(borderSize());
|
||||
}
|
||||
|
||||
BorderSize PreviewSettings::borderSize() const
|
||||
{
|
||||
return m_borderSizes->index(m_borderSize).data(Qt::UserRole).value<BorderSize>();
|
||||
}
|
||||
|
||||
void PreviewSettings::setFont(const QFont &font)
|
||||
{
|
||||
if (m_font == font) {
|
||||
return;
|
||||
}
|
||||
m_font = font;
|
||||
emit fontChanged(m_font);
|
||||
}
|
||||
|
||||
Settings::Settings(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
connect(this, &Settings::bridgeChanged, this, &Settings::createSettings);
|
||||
}
|
||||
|
||||
Settings::~Settings() = default;
|
||||
|
||||
void Settings::setBridge(PreviewBridge *bridge)
|
||||
{
|
||||
if (m_bridge == bridge) {
|
||||
return;
|
||||
}
|
||||
m_bridge = bridge;
|
||||
emit bridgeChanged();
|
||||
}
|
||||
|
||||
PreviewBridge *Settings::bridge() const
|
||||
{
|
||||
return m_bridge.data();
|
||||
}
|
||||
|
||||
void Settings::createSettings()
|
||||
{
|
||||
if (m_bridge.isNull()) {
|
||||
m_settings.clear();
|
||||
} else {
|
||||
m_settings = QSharedPointer<KDecoration2::DecorationSettings>::create(m_bridge.data());
|
||||
}
|
||||
emit settingsChanged();
|
||||
}
|
||||
|
||||
QSharedPointer<DecorationSettings> Settings::settings() const
|
||||
{
|
||||
return m_settings;
|
||||
}
|
||||
|
||||
DecorationSettings *Settings::settingsPointer() const
|
||||
{
|
||||
return m_settings.data();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
184
kcmkwin/kwindecoration/declarative-plugin/previewsettings.h
Normal file
184
kcmkwin/kwindecoration/declarative-plugin/previewsettings.h
Normal file
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* Copyright 2014 Martin Gräßlin <mgraesslin@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef KDECOARTIONS_PREVIEW_SETTINGS_H
|
||||
#define KDECOARTIONS_PREVIEW_SETTINGS_H
|
||||
|
||||
#include <KDecoration2/Private/DecorationSettingsPrivate>
|
||||
#include <KDecoration2/DecorationSettings>
|
||||
#include <QObject>
|
||||
#include <QAbstractListModel>
|
||||
|
||||
namespace KDecoration2
|
||||
{
|
||||
|
||||
namespace Preview
|
||||
{
|
||||
class PreviewBridge;
|
||||
|
||||
class ButtonsModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ButtonsModel(const QList< DecorationButtonType > &buttons, QObject *parent = 0);
|
||||
virtual ~ButtonsModel();
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
QHash< int, QByteArray > roleNames() const override;
|
||||
|
||||
QList< DecorationButtonType > buttons() const {
|
||||
return m_buttons;
|
||||
}
|
||||
|
||||
Q_INVOKABLE void remove(int index);
|
||||
Q_INVOKABLE void up(int index);
|
||||
Q_INVOKABLE void down(int index);
|
||||
|
||||
void add(DecorationButtonType type);
|
||||
|
||||
private:
|
||||
QList< DecorationButtonType > m_buttons;
|
||||
};
|
||||
|
||||
class BorderSizesModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit BorderSizesModel(QObject *parent = 0);
|
||||
virtual ~BorderSizesModel();
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
QHash< int, QByteArray > roleNames() const override;
|
||||
private:
|
||||
QList<BorderSize> m_borders = QList<BorderSize>({
|
||||
BorderSize::None,
|
||||
BorderSize::NoSides,
|
||||
BorderSize::Tiny,
|
||||
BorderSize::Normal,
|
||||
BorderSize::Large,
|
||||
BorderSize::VeryLarge,
|
||||
BorderSize::Huge,
|
||||
BorderSize::VeryHuge,
|
||||
BorderSize::Oversized
|
||||
});
|
||||
};
|
||||
|
||||
class PreviewSettings : public QObject, public DecorationSettingsPrivate
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool onAllDesktopsAvailable READ isOnAllDesktopsAvailable WRITE setOnAllDesktopsAvailable NOTIFY onAllDesktopsAvailableChanged)
|
||||
Q_PROPERTY(bool alphaChannelSupported READ isAlphaChannelSupported WRITE setAlphaChannelSupported NOTIFY alphaChannelSupportedChanged)
|
||||
Q_PROPERTY(bool closeOnDoubleClickOnMenu READ isCloseOnDoubleClickOnMenu WRITE setCloseOnDoubleClickOnMenu NOTIFY closeOnDoubleClickOnMenuChanged)
|
||||
Q_PROPERTY(QAbstractItemModel *leftButtonsModel READ leftButtonsModel CONSTANT)
|
||||
Q_PROPERTY(QAbstractItemModel *rightButtonsModel READ rightButtonsModel CONSTANT)
|
||||
Q_PROPERTY(QAbstractItemModel *availableButtonsModel READ availableButtonsModel CONSTANT)
|
||||
Q_PROPERTY(QAbstractItemModel *borderSizesModel READ borderSizesModel CONSTANT)
|
||||
Q_PROPERTY(int borderSizesIndex READ borderSizesIndex WRITE setBorderSizesIndex NOTIFY borderSizesIndexChanged)
|
||||
Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged)
|
||||
public:
|
||||
explicit PreviewSettings(DecorationSettings *parent);
|
||||
virtual ~PreviewSettings();
|
||||
bool isAlphaChannelSupported() const override;
|
||||
bool isOnAllDesktopsAvailable() const override;
|
||||
bool isCloseOnDoubleClickOnMenu() const override {
|
||||
return m_closeOnDoubleClick;
|
||||
}
|
||||
BorderSize borderSize() const override;
|
||||
|
||||
void setOnAllDesktopsAvailable(bool available);
|
||||
void setAlphaChannelSupported(bool supported);
|
||||
void setCloseOnDoubleClickOnMenu(bool enabled);
|
||||
|
||||
QAbstractItemModel *leftButtonsModel() const {
|
||||
return m_leftButtons;
|
||||
}
|
||||
QAbstractItemModel *rightButtonsModel() const {
|
||||
return m_rightButtons;
|
||||
}
|
||||
QAbstractItemModel *availableButtonsModel() const {
|
||||
return m_availableButtons;
|
||||
}
|
||||
QAbstractItemModel *borderSizesModel() const {
|
||||
return m_borderSizes;
|
||||
}
|
||||
|
||||
QList< DecorationButtonType > decorationButtonsLeft() const override;
|
||||
QList< DecorationButtonType > decorationButtonsRight() const override;
|
||||
|
||||
Q_INVOKABLE void addButtonToLeft(int row);
|
||||
Q_INVOKABLE void addButtonToRight(int row);
|
||||
|
||||
int borderSizesIndex() const {
|
||||
return m_borderSize;
|
||||
}
|
||||
void setBorderSizesIndex(int index);
|
||||
|
||||
QFont font() const {
|
||||
return m_font;
|
||||
}
|
||||
void setFont(const QFont &font);
|
||||
|
||||
Q_SIGNALS:
|
||||
void onAllDesktopsAvailableChanged(bool);
|
||||
void alphaChannelSupportedChanged(bool);
|
||||
void closeOnDoubleClickOnMenuChanged(bool);
|
||||
void borderSizesIndexChanged(int);
|
||||
void fontChanged(const QFont &);
|
||||
|
||||
private:
|
||||
bool m_alphaChannelSupported;
|
||||
bool m_onAllDesktopsAvailable;
|
||||
bool m_closeOnDoubleClick;
|
||||
ButtonsModel *m_leftButtons;
|
||||
ButtonsModel *m_rightButtons;
|
||||
ButtonsModel *m_availableButtons;
|
||||
BorderSizesModel *m_borderSizes;
|
||||
int m_borderSize;
|
||||
QFont m_font;
|
||||
};
|
||||
|
||||
class Settings : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(KDecoration2::Preview::PreviewBridge *bridge READ bridge WRITE setBridge NOTIFY bridgeChanged)
|
||||
Q_PROPERTY(KDecoration2::DecorationSettings *settings READ settingsPointer NOTIFY settingsChanged)
|
||||
public:
|
||||
explicit Settings(QObject *parent = nullptr);
|
||||
virtual ~Settings();
|
||||
|
||||
PreviewBridge *bridge() const;
|
||||
void setBridge(PreviewBridge *bridge);
|
||||
|
||||
QSharedPointer<DecorationSettings> settings() const;
|
||||
DecorationSettings *settingsPointer() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void bridgeChanged();
|
||||
void settingsChanged();
|
||||
|
||||
private:
|
||||
void createSettings();
|
||||
QPointer<PreviewBridge> m_bridge;
|
||||
QSharedPointer<KDecoration2::DecorationSettings> m_settings;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
2
kcmkwin/kwindecoration/declarative-plugin/qmldir
Normal file
2
kcmkwin/kwindecoration/declarative-plugin/qmldir
Normal file
|
@ -0,0 +1,2 @@
|
|||
module org.kde.kwin.private.kdecoration
|
||||
plugin kdecorationprivatedeclarative
|
|
@ -1,370 +1,164 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2009 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
/*
|
||||
* Copyright 2014 Martin Gräßlin <mgraesslin@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "decorationmodel.h"
|
||||
#include "preview.h"
|
||||
// kwin
|
||||
#include <kdecorationfactory.h>
|
||||
// Qt
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QApplication>
|
||||
#include <QStandardPaths>
|
||||
// KDecoration2
|
||||
#include <KDecoration2/DecorationSettings>
|
||||
#include <KDecoration2/Decoration>
|
||||
// KDE
|
||||
#include <KConfigGroup>
|
||||
#include <KDesktopFile>
|
||||
#include <KLocalizedString>
|
||||
#include <KServiceTypeTrader>
|
||||
#include <KPluginInfo>
|
||||
#include <KPluginLoader>
|
||||
#include <KPluginFactory>
|
||||
#include <KPluginTrader>
|
||||
#include "kwindecoration.h"
|
||||
// Qt
|
||||
#include <QDebug>
|
||||
|
||||
/* WARNING -------------------------------------------------------------------------
|
||||
* it is *ABSOLUTELY* mandatory to manage loadPlugin() and destroyPreviousPlugin()
|
||||
* using disablePreview()
|
||||
*
|
||||
* loadPlugin() moves the present factory pointer to "old_fact" which is then deleted
|
||||
* by the succeeding destroyPreviousPlugin()
|
||||
*
|
||||
* So if you loaded a new plugin and that changed the current factory, call disablePreview()
|
||||
* BEFORE the following destroyPreviousPlugin() destroys the factory for the current m_preview->deco->factory
|
||||
* (which is invoked on deco deconstruction)
|
||||
* WARNING ------------------------------------------------------------------------ */
|
||||
|
||||
static const QString s_auroraePluginName = QStringLiteral("aurorae");
|
||||
|
||||
namespace KWin
|
||||
namespace KDecoration2
|
||||
{
|
||||
|
||||
DecorationModel::DecorationModel(KSharedConfigPtr config, QObject* parent)
|
||||
namespace Configuration
|
||||
{
|
||||
static const QString s_pluginName = QStringLiteral("org.kde.kdecoration2");
|
||||
|
||||
DecorationsModel::DecorationsModel(QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
, m_plugins(new KDecorationPreviewPlugins(config))
|
||||
, m_preview(new KDecorationPreview())
|
||||
, m_customButtons(false)
|
||||
, m_options(new KDecorationPreviewOptions)
|
||||
{
|
||||
QHash<int, QByteArray> roleNames;
|
||||
roleNames[Qt::DisplayRole] = "display";
|
||||
roleNames[TypeRole] = "type";
|
||||
roleNames[AuroraeNameRole] = "auroraeThemeName";
|
||||
roleNames[QmlMainScriptRole] = "mainScript";
|
||||
roleNames[BorderSizeRole] = "borderSize";
|
||||
roleNames[ButtonSizeRole] = "buttonSize";
|
||||
roleNames[LibraryNameRole] = "library";
|
||||
setRoleNames(roleNames);
|
||||
m_config = KSharedConfig::openConfig("auroraerc");
|
||||
findDecorations();
|
||||
}
|
||||
|
||||
DecorationModel::~DecorationModel()
|
||||
DecorationsModel::~DecorationsModel() = default;
|
||||
|
||||
int DecorationsModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
delete m_preview;
|
||||
delete m_plugins;
|
||||
if (parent.isValid()) {
|
||||
return 0;
|
||||
}
|
||||
return m_plugins.size();
|
||||
}
|
||||
|
||||
void DecorationModel::reload()
|
||||
QVariant DecorationsModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
m_decorations.clear();
|
||||
findDecorations();
|
||||
if (!index.isValid() || index.column() != 0 || index.row() < 0 || index.row() >= int(m_plugins.size())) {
|
||||
return QVariant();
|
||||
}
|
||||
const Data &d = m_plugins.at(index.row());
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
return d.visibleName;
|
||||
case Qt::UserRole +4:
|
||||
return d.pluginName;
|
||||
case Qt::UserRole +5:
|
||||
return d.themeName;
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
// Find all theme desktop files in all 'data' dirs owned by kwin.
|
||||
// And insert these into a DecorationInfo structure
|
||||
void DecorationModel::findDecorations()
|
||||
QHash< int, QByteArray > DecorationsModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles({
|
||||
{Qt::DisplayRole, QByteArrayLiteral("display")},
|
||||
{Qt::UserRole + 4, QByteArrayLiteral("plugin")},
|
||||
{Qt::UserRole + 5, QByteArrayLiteral("theme")}
|
||||
});
|
||||
return roles;
|
||||
}
|
||||
|
||||
static bool isThemeEngine(const QVariantMap &decoSettingsMap)
|
||||
{
|
||||
auto it = decoSettingsMap.find(QStringLiteral("themes"));
|
||||
if (it == decoSettingsMap.end()) {
|
||||
return false;
|
||||
}
|
||||
return it.value().toBool();
|
||||
}
|
||||
|
||||
static QString themeListKeyword(const QVariantMap &decoSettingsMap)
|
||||
{
|
||||
auto it = decoSettingsMap.find(QStringLiteral("themeListKeyword"));
|
||||
if (it == decoSettingsMap.end()) {
|
||||
return QString();
|
||||
}
|
||||
return it.value().toString();
|
||||
}
|
||||
|
||||
void DecorationsModel::init()
|
||||
{
|
||||
beginResetModel();
|
||||
const auto decorations = KPluginTrader::self()->query(QStringLiteral("kwin/kdecorations"));
|
||||
for (const KPluginInfo &plugin : decorations) {
|
||||
if (plugin.pluginName() == s_auroraePluginName) {
|
||||
// read the Aurorae themes
|
||||
findAuroraeThemes();
|
||||
const auto plugins = KPluginTrader::self()->query(s_pluginName, s_pluginName);
|
||||
for (const auto &info : plugins) {
|
||||
KPluginLoader loader(info.libraryPath());
|
||||
KPluginFactory *factory = loader.factory();
|
||||
if (!factory) {
|
||||
continue;
|
||||
}
|
||||
DecorationModelData data;
|
||||
data.name = plugin.name();
|
||||
data.pluginName = plugin.pluginName();
|
||||
data.type = DecorationModelData::NativeDecoration;
|
||||
data.borderSize = KDecorationDefines::BorderNormal;
|
||||
data.closeDblClick = false;
|
||||
data.comment = plugin.comment();
|
||||
data.author = plugin.author();
|
||||
data.email = plugin.email();
|
||||
data.version = plugin.version();
|
||||
data.license = plugin.license();
|
||||
data.website = plugin.website();
|
||||
m_decorations.append(data);
|
||||
}
|
||||
auto metadata = loader.metaData().value(QStringLiteral("MetaData")).toObject().value(s_pluginName);
|
||||
if (!metadata.isUndefined()) {
|
||||
const auto decoSettingsMap = metadata.toObject().toVariantMap();
|
||||
if (isThemeEngine(decoSettingsMap)) {
|
||||
const QString keyword = themeListKeyword(decoSettingsMap);
|
||||
if (keyword.isNull()) {
|
||||
// We cannot list the themes
|
||||
continue;
|
||||
}
|
||||
QScopedPointer<QObject> themeFinder(factory->create<QObject>(keyword));
|
||||
if (themeFinder.isNull()) {
|
||||
continue;
|
||||
}
|
||||
QVariant themes = themeFinder->property("themes");
|
||||
if (!themes.isValid()) {
|
||||
continue;
|
||||
}
|
||||
const auto themesMap = themes.toMap();
|
||||
for (auto it = themesMap.begin(); it != themesMap.end(); ++it) {
|
||||
Data d;
|
||||
d.pluginName = info.pluginName();
|
||||
d.themeName = it.value().toString();
|
||||
d.visibleName = it.key();
|
||||
m_plugins.emplace_back(std::move(d));
|
||||
}
|
||||
|
||||
KService::List offers = KServiceTypeTrader::self()->query("KWin/Decoration");
|
||||
foreach (KService::Ptr service, offers) {
|
||||
DecorationModelData data;
|
||||
data.name = service->name();
|
||||
data.pluginName = s_auroraePluginName;
|
||||
data.type = DecorationModelData::QmlDecoration;
|
||||
data.auroraeName = service->property("X-KDE-PluginInfo-Name").toString();
|
||||
QString scriptName = service->property("X-Plasma-MainScript").toString();
|
||||
data.configTranslationDomain = service->property(QStringLiteral("X-KWin-Config-TranslationDomain")).toString();
|
||||
data.qmlPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kwin/decorations/" + data.auroraeName + "/contents/" + scriptName);
|
||||
if (data.qmlPath.isEmpty()) {
|
||||
// not a valid QML theme
|
||||
continue;
|
||||
// it's a theme engine, we don't want to show this entry
|
||||
continue;
|
||||
}
|
||||
}
|
||||
KConfigGroup config(m_config, data.auroraeName);
|
||||
data.borderSize = (KDecorationDefines::BorderSize)config.readEntry< int >("BorderSize", KDecorationDefines::BorderNormal);
|
||||
data.buttonSize = (KDecorationDefines::BorderSize)config.readEntry< int >("ButtonSize", KDecorationDefines::BorderNormal);
|
||||
data.closeDblClick = config.readEntry< bool >("CloseOnDoubleClickMenuButton", false);
|
||||
data.comment = service->comment();
|
||||
KPluginInfo info(service);
|
||||
data.author = info.author();
|
||||
data.email= info.email();
|
||||
data.version = info.version();
|
||||
data.license = info.license();
|
||||
data.website = info.website();
|
||||
m_decorations.append(data);
|
||||
Data data;
|
||||
data.pluginName = info.pluginName();
|
||||
data.visibleName = info.name().isEmpty() ? info.pluginName() : info.name();
|
||||
|
||||
m_plugins.emplace_back(std::move(data));
|
||||
}
|
||||
qSort(m_decorations.begin(), m_decorations.end(), DecorationModelData::less);
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void DecorationModel::findAuroraeThemes()
|
||||
QModelIndex DecorationsModel::findDecoration(const QString &pluginName, const QString &themeName) const
|
||||
{
|
||||
// get all destop themes
|
||||
QStringList themes;
|
||||
const QStringList dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, "aurorae/themes/", QStandardPaths::LocateDirectory);
|
||||
QStringList themeDirectories;
|
||||
for (const QString & dir : dirs) {
|
||||
QDir directory = QDir(dir);
|
||||
for (const QString &themeDir : directory.entryList(QDir::AllDirs | QDir::NoDotAndDotDot)) {
|
||||
themeDirectories << dir + themeDir;
|
||||
auto it = std::find_if(m_plugins.cbegin(), m_plugins.cend(),
|
||||
[pluginName, themeName](const Data &d) {
|
||||
return d.pluginName == pluginName && d.themeName == themeName;
|
||||
}
|
||||
);
|
||||
if (it == m_plugins.cend()) {
|
||||
return QModelIndex();
|
||||
}
|
||||
for (const QString &dir : themeDirectories) {
|
||||
for (const QString & file : QDir(dir).entryList(QStringList() << QStringLiteral("metadata.desktop"))) {
|
||||
themes.append(dir + '/' + file);
|
||||
}
|
||||
}
|
||||
foreach (const QString & theme, themes) {
|
||||
int themeSepIndex = theme.lastIndexOf('/', -1);
|
||||
QString themeRoot = theme.left(themeSepIndex);
|
||||
int themeNameSepIndex = themeRoot.lastIndexOf('/', -1);
|
||||
QString packageName = themeRoot.right(themeRoot.length() - themeNameSepIndex - 1);
|
||||
|
||||
KDesktopFile df(theme);
|
||||
QString name = df.readName();
|
||||
if (name.isEmpty()) {
|
||||
name = packageName;
|
||||
}
|
||||
|
||||
DecorationModelData data;
|
||||
data.name = name;
|
||||
data.pluginName = s_auroraePluginName;
|
||||
data.type = DecorationModelData::AuroraeDecoration;
|
||||
data.auroraeName = packageName;
|
||||
KConfigGroup config(m_config, data.auroraeName);
|
||||
data.borderSize = (KDecorationDefines::BorderSize)config.readEntry< int >("BorderSize", KDecorationDefines::BorderNormal);
|
||||
data.buttonSize = (KDecorationDefines::BorderSize)config.readEntry< int >("ButtonSize", KDecorationDefines::BorderNormal);
|
||||
data.closeDblClick = config.readEntry< bool >("CloseOnDoubleClickMenuButton", false);
|
||||
metaData(data, df);
|
||||
m_decorations.append(data);
|
||||
}
|
||||
const auto distance = std::distance(m_plugins.cbegin(), it);
|
||||
return createIndex(distance, 0);
|
||||
}
|
||||
|
||||
void DecorationModel::metaData(DecorationModelData& data, const KDesktopFile& df)
|
||||
{
|
||||
data.comment = df.readComment();
|
||||
data.author = df.desktopGroup().readEntry("X-KDE-PluginInfo-Author", QString());
|
||||
data.email = df.desktopGroup().readEntry("X-KDE-PluginInfo-Email", QString());
|
||||
data.version = df.desktopGroup().readEntry("X-KDE-PluginInfo-Version", QString());
|
||||
data.license = df.desktopGroup().readEntry("X-KDE-PluginInfo-License", QString());
|
||||
data.website = df.desktopGroup().readEntry("X-KDE-PluginInfo-Website", QString());
|
||||
}
|
||||
|
||||
int DecorationModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
return m_decorations.count();
|
||||
}
|
||||
|
||||
QVariant DecorationModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
switch(role) {
|
||||
case Qt::DisplayRole:
|
||||
case NameRole:
|
||||
return m_decorations[ index.row()].name;
|
||||
case LibraryNameRole:
|
||||
return m_decorations[ index.row()].pluginName;
|
||||
case TypeRole:
|
||||
return m_decorations[ index.row()].type;
|
||||
case AuroraeNameRole:
|
||||
return m_decorations[ index.row()].auroraeName;
|
||||
case PackageDescriptionRole:
|
||||
return m_decorations[ index.row()].comment;
|
||||
case PackageAuthorRole:
|
||||
return m_decorations[ index.row()].author;
|
||||
case PackageEmailRole:
|
||||
return m_decorations[ index.row()].email;
|
||||
case PackageWebsiteRole:
|
||||
return m_decorations[ index.row()].website;
|
||||
case PackageVersionRole:
|
||||
return m_decorations[ index.row()].version;
|
||||
case PackageLicenseRole:
|
||||
return m_decorations[ index.row()].license;
|
||||
case BorderSizeRole:
|
||||
return static_cast< int >(m_decorations[ index.row()].borderSize);
|
||||
case BorderSizesRole: {
|
||||
QList< QVariant > sizes;
|
||||
const bool mustDisablePreview = m_plugins->factory() && m_plugins->factory() == m_preview->factory();
|
||||
if (m_plugins->loadPlugin(m_decorations[index.row()].pluginName) && m_plugins->factory()) {
|
||||
foreach (KDecorationDefines::BorderSize size, m_plugins->factory()->borderSizes()) // krazy:exclude=foreach
|
||||
sizes << int(size);
|
||||
if (mustDisablePreview) // it's nuked with destroyPreviousPlugin()
|
||||
m_preview->disablePreview(); // so we need to get rid of m_preview->deco first
|
||||
m_plugins->destroyPreviousPlugin();
|
||||
}
|
||||
return sizes;
|
||||
}
|
||||
case ButtonSizeRole:
|
||||
if (m_decorations[ index.row()].type == DecorationModelData::AuroraeDecoration ||
|
||||
m_decorations[ index.row()].type == DecorationModelData::QmlDecoration)
|
||||
return static_cast< int >(m_decorations[ index.row()].buttonSize);
|
||||
else
|
||||
return QVariant();
|
||||
case QmlMainScriptRole:
|
||||
return m_decorations[ index.row()].qmlPath;
|
||||
case CloseOnDblClickRole:
|
||||
return m_decorations[index.row()].closeDblClick;
|
||||
case ConfigTranslationDomain:
|
||||
return m_decorations[index.row()].configTranslationDomain;
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
bool DecorationModel::setData(const QModelIndex& index, const QVariant& value, int role)
|
||||
{
|
||||
if (!index.isValid() || (role != BorderSizeRole && role != ButtonSizeRole && role != CloseOnDblClickRole))
|
||||
return QAbstractItemModel::setData(index, value, role);
|
||||
|
||||
const DecorationModelData::DecorationType type = m_decorations[ index.row()].type;
|
||||
|
||||
if (role == BorderSizeRole) {
|
||||
m_decorations[ index.row()].borderSize = (KDecorationDefines::BorderSize)value.toInt();
|
||||
if (type == DecorationModelData::AuroraeDecoration || type == DecorationModelData::QmlDecoration) {
|
||||
KConfigGroup config(m_config, m_decorations[ index.row()].auroraeName);
|
||||
config.writeEntry("BorderSize", value.toInt());
|
||||
config.sync();
|
||||
}
|
||||
emit dataChanged(index, index);
|
||||
emit configChanged(m_decorations[ index.row()].auroraeName);
|
||||
return true;
|
||||
}
|
||||
if (role == ButtonSizeRole && (type == DecorationModelData::AuroraeDecoration || type == DecorationModelData::QmlDecoration)) {
|
||||
m_decorations[ index.row()].buttonSize = (KDecorationDefines::BorderSize)value.toInt();
|
||||
KConfigGroup config(m_config, m_decorations[ index.row()].auroraeName);
|
||||
config.writeEntry("ButtonSize", value.toInt());
|
||||
config.sync();
|
||||
emit dataChanged(index, index);
|
||||
emit configChanged(m_decorations[ index.row()].auroraeName);
|
||||
return true;
|
||||
}
|
||||
if (role == CloseOnDblClickRole && (type == DecorationModelData::AuroraeDecoration || type == DecorationModelData::QmlDecoration)) {
|
||||
if (m_decorations[ index.row()].closeDblClick == value.toBool()) {
|
||||
return false;
|
||||
}
|
||||
m_decorations[ index.row()].closeDblClick = value.toBool();
|
||||
KConfigGroup config(m_config, m_decorations[ index.row()].auroraeName);
|
||||
config.writeEntry("CloseOnDoubleClickMenuButton", value.toBool());
|
||||
config.sync();
|
||||
emit dataChanged(index, index);
|
||||
emit configChanged(m_decorations[ index.row()].auroraeName);
|
||||
return true;
|
||||
}
|
||||
return QAbstractItemModel::setData(index, value, role);
|
||||
}
|
||||
|
||||
|
||||
void DecorationModel::changeButtons(const KWin::DecorationButtons *buttons)
|
||||
{
|
||||
m_customButtons = buttons->customPositions();
|
||||
m_options->setCustomTitleButtonsEnabled(m_customButtons);
|
||||
m_options->setCustomTitleButtons(buttons->leftButtons(), buttons->rightButtons());
|
||||
}
|
||||
|
||||
void DecorationModel::setButtons(bool custom, const QList<KDecorationDefines::DecorationButton> &left, const QList<KDecorationDefines::DecorationButton> &right)
|
||||
{
|
||||
m_customButtons = custom;
|
||||
m_options->setCustomTitleButtons(left, right);
|
||||
}
|
||||
|
||||
QModelIndex DecorationModel::indexOfLibrary(const QString& libraryName) const
|
||||
{
|
||||
for (int i = 0; i < m_decorations.count(); i++) {
|
||||
if (m_decorations.at(i).pluginName.compare(libraryName) == 0)
|
||||
return index(i);
|
||||
}
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
QModelIndex DecorationModel::indexOfName(const QString& decoName) const
|
||||
{
|
||||
for (int i = 0; i < m_decorations.count(); i++) {
|
||||
if (m_decorations.at(i).name.compare(decoName) == 0)
|
||||
return index(i);
|
||||
}
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
QModelIndex DecorationModel::indexOfAuroraeName(const QString &auroraeName, const QString &type) const
|
||||
{
|
||||
for (int i = 0; i < m_decorations.count(); i++) {
|
||||
const DecorationModelData& data = m_decorations.at(i);
|
||||
if (type == "aurorae" && data.type == DecorationModelData::AuroraeDecoration &&
|
||||
data.auroraeName.compare(auroraeName) == 0)
|
||||
return index(i);
|
||||
if (type == "qml" && data.type == DecorationModelData::QmlDecoration &&
|
||||
data.auroraeName.compare(auroraeName) == 0)
|
||||
return index(i);
|
||||
}
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
void DecorationModel::setBorderSize(const QModelIndex& index, KDecorationDefines::BorderSize size)
|
||||
{
|
||||
if (!index.isValid() || m_decorations[ index.row()].type == DecorationModelData::AuroraeDecoration || m_decorations[ index.row()].type == DecorationModelData::QmlDecoration)
|
||||
return;
|
||||
m_decorations[ index.row()].borderSize = size;
|
||||
}
|
||||
|
||||
QVariant DecorationModel::readConfig(const QString &themeName, const QString &key, const QVariant &defaultValue)
|
||||
{
|
||||
return m_config->group(themeName).readEntry(key, defaultValue);
|
||||
}
|
||||
|
||||
void DecorationModel::notifyConfigChanged(const QModelIndex &index)
|
||||
{
|
||||
if (!index.isValid()) {
|
||||
return;
|
||||
}
|
||||
emit configChanged(m_decorations[index.row()].auroraeName);
|
||||
}
|
||||
|
||||
} // namespace KWin
|
||||
|
|
|
@ -1,139 +1,59 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
/*
|
||||
* Copyright 2014 Martin Gräßlin <mgraesslin@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef KDECORATION_DECORATIONS_MODEL_H
|
||||
#define KDECORATION_DECORATIONS_MODEL_H
|
||||
|
||||
Copyright (C) 2009 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef KWIN_DECORATIONMODEL_H
|
||||
#define KWIN_DECORATIONMODEL_H
|
||||
#include <QAbstractListModel>
|
||||
#include <QPixmap>
|
||||
#include <KConfig>
|
||||
#include <KSharedConfig>
|
||||
#include <kdecoration.h>
|
||||
|
||||
class QWidget;
|
||||
class KDesktopFile;
|
||||
class KDecorationPlugins;
|
||||
class KDecorationPreview;
|
||||
class KDecorationPreviewOptions;
|
||||
|
||||
namespace KWin
|
||||
namespace KDecoration2
|
||||
{
|
||||
|
||||
class DecorationButtons;
|
||||
|
||||
class DecorationModelData
|
||||
namespace Configuration
|
||||
{
|
||||
public:
|
||||
enum DecorationType {
|
||||
NativeDecoration = 0,
|
||||
AuroraeDecoration = 1,
|
||||
QmlDecoration = 2
|
||||
};
|
||||
QString name;
|
||||
QString pluginName;
|
||||
DecorationType type;
|
||||
QString comment;
|
||||
QString author;
|
||||
QString email;
|
||||
QString website;
|
||||
QString version;
|
||||
QString license;
|
||||
QString auroraeName;
|
||||
QString qmlPath;
|
||||
QString configTranslationDomain;
|
||||
KDecorationDefines::BorderSize borderSize;
|
||||
KDecorationDefines::BorderSize buttonSize;
|
||||
/**
|
||||
* Whether the window gets closed on double clicking the Menu Button.
|
||||
* Only applies for Aurorae and QML Decoration.
|
||||
**/
|
||||
bool closeDblClick;
|
||||
|
||||
static bool less(const DecorationModelData& a, const DecorationModelData& b) {
|
||||
return a.name < b.name;
|
||||
}
|
||||
};
|
||||
|
||||
class DecorationModel : public QAbstractListModel
|
||||
class DecorationsModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum {
|
||||
NameRole = Qt::UserRole,
|
||||
LibraryNameRole = Qt::UserRole + 1,
|
||||
TypeRole = Qt::UserRole + 3,
|
||||
AuroraeNameRole = Qt::UserRole + 4,
|
||||
PackageDescriptionRole = Qt::UserRole + 5,
|
||||
PackageAuthorRole = Qt::UserRole + 6,
|
||||
PackageEmailRole = Qt::UserRole + 7,
|
||||
PackageWebsiteRole = Qt::UserRole + 8,
|
||||
PackageVersionRole = Qt::UserRole + 9,
|
||||
PackageLicenseRole = Qt::UserRole + 10,
|
||||
BorderSizeRole = Qt::UserRole + 11,
|
||||
BorderSizesRole = Qt::UserRole + 12,
|
||||
ButtonSizeRole = Qt::UserRole + 13,
|
||||
QmlMainScriptRole = Qt::UserRole + 14,
|
||||
CloseOnDblClickRole = Qt::UserRole + 15,
|
||||
ConfigTranslationDomain = Qt::UserRole + 16
|
||||
};
|
||||
explicit DecorationModel(KSharedConfigPtr config, QObject* parent = nullptr);
|
||||
~DecorationModel();
|
||||
explicit DecorationsModel(QObject *parent = nullptr);
|
||||
virtual ~DecorationsModel();
|
||||
|
||||
virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
|
||||
virtual int rowCount(const QModelIndex& parent = QModelIndex()) const;
|
||||
virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole);
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QHash< int, QByteArray > roleNames() const override;
|
||||
|
||||
void reload();
|
||||
QModelIndex findDecoration(const QString &pluginName, const QString &themeName = QString()) const;
|
||||
|
||||
/**
|
||||
* Changes the button state and regenerates the preview.
|
||||
*/
|
||||
void changeButtons(const DecorationButtons *buttons);
|
||||
/**
|
||||
* Changes the button state without regenerating the preview.
|
||||
*/
|
||||
void setButtons(bool custom, const QList<KDecorationDefines::DecorationButton>& left, const QList<KDecorationDefines::DecorationButton>& right);
|
||||
public Q_SLOTS:
|
||||
void init();
|
||||
|
||||
void setBorderSize(const QModelIndex& index, KDecorationDefines::BorderSize size);
|
||||
|
||||
QModelIndex indexOfLibrary(const QString& libraryName) const;
|
||||
QModelIndex indexOfName(const QString& decoName) const;
|
||||
QModelIndex indexOfAuroraeName(const QString& auroraeName, const QString& type) const;
|
||||
|
||||
Q_INVOKABLE QVariant readConfig(const QString &themeName, const QString &key, const QVariant &defaultValue = QVariant());
|
||||
|
||||
void notifyConfigChanged(const QModelIndex &index);
|
||||
|
||||
Q_SIGNALS:
|
||||
void configChanged(QString themeName);
|
||||
private:
|
||||
void findDecorations();
|
||||
void findAuroraeThemes();
|
||||
void metaData(DecorationModelData& data, const KDesktopFile& df);
|
||||
QList<DecorationModelData> m_decorations;
|
||||
KDecorationPlugins* m_plugins;
|
||||
KDecorationPreview* m_preview;
|
||||
bool m_customButtons;
|
||||
KSharedConfigPtr m_config;
|
||||
QScopedPointer<KDecorationPreviewOptions> m_options;
|
||||
struct Data {
|
||||
QString pluginName;
|
||||
QString themeName;
|
||||
QString visibleName;
|
||||
};
|
||||
std::vector<Data> m_plugins;
|
||||
};
|
||||
|
||||
} // namespace KWin
|
||||
}
|
||||
}
|
||||
|
||||
#endif // KWIN_DECORATIONMODEL_H
|
||||
#endif
|
||||
|
|
128
kcmkwin/kwindecoration/kcm.cpp
Normal file
128
kcmkwin/kwindecoration/kcm.cpp
Normal file
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Copyright 2014 Martin Gräßlin <mgraesslin@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "kcm.h"
|
||||
#include "decorationmodel.h"
|
||||
|
||||
// KDE
|
||||
#include <KConfigGroup>
|
||||
#include <KPluginFactory>
|
||||
#include <KSharedConfig>
|
||||
// Qt
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusMessage>
|
||||
#include <QQmlContext>
|
||||
#include <QQmlEngine>
|
||||
#include <QQuickItem>
|
||||
#include <QQuickWidget>
|
||||
#include <QStandardPaths>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
K_PLUGIN_FACTORY(KDecorationFactory,
|
||||
registerPlugin<KDecoration2::Configuration::ConfigurationModule>();
|
||||
)
|
||||
|
||||
namespace KDecoration2
|
||||
{
|
||||
|
||||
namespace Configuration
|
||||
{
|
||||
static const QString s_pluginName = QStringLiteral("org.kde.kdecoration2");
|
||||
static const QString s_defaultPlugin = QStringLiteral("org.kde.breeze");
|
||||
|
||||
ConfigurationModule::ConfigurationModule(QWidget *parent, const QVariantList &args)
|
||||
: KCModule(parent, args)
|
||||
, m_view(new QQuickWidget(this))
|
||||
, m_model(new DecorationsModel(this))
|
||||
{
|
||||
m_view->rootContext()->setContextProperty(QStringLiteral("decorationsModel"), m_model);
|
||||
m_view->rootContext()->setContextProperty("highlightColor", QPalette().color(QPalette::Highlight));
|
||||
m_view->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||
m_view->setSource(QUrl::fromLocalFile(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kwin/kcm_kwindecoration/main.qml"))));
|
||||
if (m_view->status() == QQuickWidget::Ready) {
|
||||
auto listView = m_view->rootObject()->findChild<QQuickItem*>("listView");
|
||||
if (listView) {
|
||||
connect(listView, SIGNAL(currentIndexChanged()), this, SLOT(changed()));
|
||||
}
|
||||
}
|
||||
|
||||
QVBoxLayout *l = new QVBoxLayout(this);
|
||||
l->addWidget(m_view);
|
||||
QMetaObject::invokeMethod(m_model, "init", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
ConfigurationModule::~ConfigurationModule() = default;
|
||||
|
||||
void ConfigurationModule::showEvent(QShowEvent *ev)
|
||||
{
|
||||
KCModule::showEvent(ev);
|
||||
}
|
||||
|
||||
void ConfigurationModule::load()
|
||||
{
|
||||
const KConfigGroup config = KSharedConfig::openConfig("kwinrc")->group(s_pluginName);
|
||||
const QString plugin = config.readEntry("library", s_defaultPlugin);
|
||||
const QString theme = config.readEntry("theme", QString());
|
||||
const QModelIndex index = m_model->findDecoration(plugin, theme);
|
||||
if (auto listView = m_view->rootObject()->findChild<QQuickItem*>("listView")) {
|
||||
listView->setProperty("currentIndex", index.isValid() ? index.row() : -1);
|
||||
}
|
||||
KCModule::load();
|
||||
}
|
||||
|
||||
void ConfigurationModule::save()
|
||||
{
|
||||
if (auto listView = m_view->rootObject()->findChild<QQuickItem*>("listView")) {
|
||||
const int currentIndex = listView->property("currentIndex").toInt();
|
||||
if (currentIndex != -1) {
|
||||
const QModelIndex index = m_model->index(currentIndex, 0);
|
||||
if (index.isValid()) {
|
||||
KConfigGroup config = KSharedConfig::openConfig("kwinrc")->group(s_pluginName);
|
||||
config.writeEntry("library", index.data(Qt::UserRole + 4).toString());
|
||||
const QString theme = index.data(Qt::UserRole +5).toString();
|
||||
if (theme.isEmpty()) {
|
||||
config.deleteEntry("theme");
|
||||
} else {
|
||||
config.writeEntry("theme", theme);
|
||||
}
|
||||
config.sync();
|
||||
}
|
||||
}
|
||||
}
|
||||
KCModule::save();
|
||||
// Send signal to all kwin instances
|
||||
QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/KWin"),
|
||||
QStringLiteral("org.kde.KWin"),
|
||||
QStringLiteral("reloadConfig"));
|
||||
QDBusConnection::sessionBus().send(message);
|
||||
}
|
||||
|
||||
void ConfigurationModule::defaults()
|
||||
{
|
||||
if (auto listView = m_view->rootObject()->findChild<QQuickItem*>("listView")) {
|
||||
const QModelIndex index = m_model->findDecoration(s_defaultPlugin);
|
||||
listView->setProperty("currentIndex", index.isValid() ? index.row() : -1);
|
||||
}
|
||||
KCModule::defaults();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#include "kcm.moc"
|
61
kcmkwin/kwindecoration/kcm.h
Normal file
61
kcmkwin/kwindecoration/kcm.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright 2014 Martin Gräßlin <mgraesslin@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef KDECORATIONS_KCM_H
|
||||
#define KDECORATIONS_KCM_H
|
||||
|
||||
#include <kcmodule.h>
|
||||
|
||||
class QQuickWidget;
|
||||
|
||||
namespace KDecoration2
|
||||
{
|
||||
namespace Preview
|
||||
{
|
||||
class PreviewBridge;
|
||||
}
|
||||
namespace Configuration
|
||||
{
|
||||
class DecorationsModel;
|
||||
|
||||
class ConfigurationModule : public KCModule
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ConfigurationModule(QWidget *parent = nullptr, const QVariantList &args = QVariantList());
|
||||
virtual ~ConfigurationModule();
|
||||
|
||||
public Q_SLOTS:
|
||||
void defaults() override;
|
||||
void load() override;
|
||||
void save() override;
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *ev) override;
|
||||
|
||||
private:
|
||||
QQuickWidget *m_view;
|
||||
DecorationsModel *m_model;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,600 +0,0 @@
|
|||
/*
|
||||
This is the new kwindecoration kcontrol module
|
||||
|
||||
Copyright (c) 2001
|
||||
Karol Szwed <gallium@kde.org>
|
||||
http://gallium.n3.net/
|
||||
Copyright 2009, 2010 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
Supports new kwin configuration plugins, and titlebar button position
|
||||
modification via dnd interface.
|
||||
|
||||
Based on original "kwintheme" (Window Borders)
|
||||
Copyright (C) 2001 Rik Hemsley (rikkus) <rik@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
*/
|
||||
// own
|
||||
#include "kwindecoration.h"
|
||||
#include "buttonsconfigdialog.h"
|
||||
#include "configdialog.h"
|
||||
#include "decorationmodel.h"
|
||||
#include "auroraetheme.h"
|
||||
#include "preview.h"
|
||||
// Qt
|
||||
#include <QtDBus/QtDBus>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QScrollBar>
|
||||
#include <QUiLoader>
|
||||
#include <QtCore/QStandardPaths>
|
||||
#include <QQmlContext>
|
||||
#include <QQuickItem>
|
||||
#include <QQuickView>
|
||||
// KDE
|
||||
#include <KAboutData>
|
||||
#include <kconfigloader.h>
|
||||
#include <KLocalizedString>
|
||||
#include <KLocalizedTranslator>
|
||||
#include <KMessageBox>
|
||||
#include <KNewStuff3/KNS3/DownloadDialog>
|
||||
#include <KConfigDialogManager>
|
||||
#include <KPluginFactory>
|
||||
|
||||
// KCModule plugin interface
|
||||
// =========================
|
||||
K_PLUGIN_FACTORY(KWinDecoFactory,
|
||||
registerPlugin<KWin::KWinDecorationModule>();
|
||||
)
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
static const QString s_defaultPluginName = QStringLiteral("Oxygen");
|
||||
|
||||
KWinDecorationForm::KWinDecorationForm(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
setupUi(this);
|
||||
}
|
||||
|
||||
|
||||
KWinDecorationModule::KWinDecorationModule(QWidget* parent, const QVariantList &)
|
||||
: KCModule(parent)
|
||||
, kwinConfig(KSharedConfig::openConfig("kwinrc"))
|
||||
, m_showTooltips(false)
|
||||
, m_model(nullptr)
|
||||
, m_proxyModel(nullptr)
|
||||
, m_configLoaded(false)
|
||||
, m_decorationButtons(new DecorationButtons(this))
|
||||
, m_listView(new QQuickView())
|
||||
, m_translator(new KLocalizedTranslator(this))
|
||||
{
|
||||
qmlRegisterType<Aurorae::AuroraeTheme>("org.kde.kwin.aurorae", 0, 1, "AuroraeTheme");
|
||||
qmlRegisterType<PreviewItem>("org.kde.kwin.kcmdecoration", 0, 1, "PreviewItem");
|
||||
m_ui = new KWinDecorationForm(this);
|
||||
m_ui->configureDecorationButton->setIcon(QIcon::fromTheme("configure"));
|
||||
m_ui->configureButtonsButton->setIcon(QIcon::fromTheme("configure"));
|
||||
m_ui->ghnsButton->setIcon(QIcon::fromTheme("get-hot-new-stuff"));
|
||||
QWidget *container = QWidget::createWindowContainer(m_listView.data(), m_ui->decorationList->viewport());
|
||||
QVBoxLayout *containerLayout = new QVBoxLayout(m_ui->decorationList->viewport());
|
||||
containerLayout->addWidget(container);
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
layout->addWidget(m_ui);
|
||||
|
||||
KAboutData *about =
|
||||
new KAboutData(QStringLiteral("kcmkwindecoration"),
|
||||
i18n("Window Decoration Control Module"),
|
||||
QString(), QString(), KAboutLicense::GPL,
|
||||
i18n("(c) 2001 Karol Szwed"));
|
||||
about->addAuthor(i18n("Karol Szwed"), QString(), "gallium@kde.org");
|
||||
setAboutData(about);
|
||||
|
||||
QCoreApplication::instance()->installTranslator(m_translator);
|
||||
}
|
||||
|
||||
|
||||
KWinDecorationModule::~KWinDecorationModule()
|
||||
{
|
||||
}
|
||||
|
||||
void KWinDecorationModule::showEvent(QShowEvent *ev)
|
||||
{
|
||||
KCModule::showEvent(ev);
|
||||
init();
|
||||
}
|
||||
|
||||
void KWinDecorationModule::init()
|
||||
{
|
||||
if (m_model) {
|
||||
// init already called
|
||||
return;
|
||||
}
|
||||
const QString mainQmlPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kwin/kcm_kwindecoration/main.qml");
|
||||
if (mainQmlPath.isNull()) {
|
||||
KMessageBox::error(this, i18n("<h1>Installation error</h1>"
|
||||
"The resource<h2>kwin/kcm_kwindecoration/main.qml</h2>could not be located in any application data path."
|
||||
"<h2>Please contact your distribution</h2>"
|
||||
"The application will now abort"), i18n("Installation Error"));
|
||||
abort();
|
||||
}
|
||||
KConfigGroup style(kwinConfig, "Style");
|
||||
|
||||
// Set up the decoration lists and other UI settings
|
||||
m_model = new DecorationModel(kwinConfig, this);
|
||||
m_proxyModel = new QSortFilterProxyModel(this);
|
||||
m_proxyModel->setSourceModel(m_model);
|
||||
m_proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
|
||||
|
||||
m_listView->setResizeMode(QQuickView::SizeRootObjectToView);
|
||||
m_listView->rootContext()->setContextProperty("decorationModel", m_proxyModel);
|
||||
m_listView->rootContext()->setContextProperty("decorationBaseModel", m_model);
|
||||
m_listView->rootContext()->setContextProperty("options", m_decorationButtons);
|
||||
m_listView->rootContext()->setContextProperty("highlightColor", m_ui->decorationList->palette().color(QPalette::Highlight));
|
||||
m_listView->rootContext()->setContextProperty("auroraeSource", QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kwin/aurorae/aurorae.qml"));
|
||||
m_listView->rootContext()->setContextProperty("decorationActiveCaptionColor", KDecoration::options()->color(ColorFont, true));
|
||||
m_listView->rootContext()->setContextProperty("decorationInactiveCaptionColor", KDecoration::options()->color(ColorFont, false));
|
||||
m_listView->rootContext()->setContextProperty("decorationActiveTitleBarColor", KDecoration::options()->color(ColorTitleBar, true));
|
||||
m_listView->rootContext()->setContextProperty("decorationInactiveTitleBarColor", KDecoration::options()->color(ColorTitleBar, false));
|
||||
m_listView->setSource(QUrl::fromLocalFile(mainQmlPath));
|
||||
|
||||
readConfig(style);
|
||||
|
||||
connect(m_listView->rootObject(), SIGNAL(currentIndexChanged()), SLOT(slotSelectionChanged()));
|
||||
connect(m_ui->configureButtonsButton, SIGNAL(clicked(bool)), this, SLOT(slotConfigureButtons()));
|
||||
connect(m_ui->ghnsButton, SIGNAL(clicked(bool)), SLOT(slotGHNSClicked()));
|
||||
connect(m_ui->searchEdit, SIGNAL(textChanged(QString)), m_proxyModel, SLOT(setFilterFixedString(QString)));
|
||||
connect(m_ui->searchEdit, SIGNAL(textChanged(QString)), m_listView->rootObject(), SLOT(returnToBounds()), Qt::QueuedConnection);
|
||||
connect(m_ui->searchEdit, SIGNAL(textChanged(QString)), SLOT(updateScrollbarRange()), Qt::QueuedConnection);
|
||||
connect(m_ui->configureDecorationButton, SIGNAL(clicked(bool)), SLOT(slotConfigureDecoration()));
|
||||
|
||||
m_ui->decorationList->disconnect(m_ui->decorationList->verticalScrollBar());
|
||||
m_ui->decorationList->verticalScrollBar()->disconnect(m_ui->decorationList);
|
||||
connect(m_listView->rootObject(), SIGNAL(contentYChanged()), SLOT(updateScrollbarValue()));
|
||||
connect(m_listView->rootObject(), SIGNAL(contentHeightChanged()), SLOT(updateScrollbarRange()));
|
||||
connect(m_ui->decorationList->verticalScrollBar(), SIGNAL(rangeChanged(int,int)), SLOT(updateScrollbarRange()));
|
||||
connect(m_ui->decorationList->verticalScrollBar(), SIGNAL(valueChanged(int)), SLOT(updateViewPosition(int)));
|
||||
|
||||
m_ui->decorationList->installEventFilter(this);
|
||||
m_ui->decorationList->viewport()->installEventFilter(this);
|
||||
QMetaObject::invokeMethod(this, "updatePreviews", Qt::QueuedConnection);
|
||||
updateScrollbarRange();
|
||||
}
|
||||
|
||||
// This is the selection handler setting
|
||||
void KWinDecorationModule::slotSelectionChanged()
|
||||
{
|
||||
emit KCModule::changed(true);
|
||||
}
|
||||
|
||||
// Reads the kwin config settings, and sets all UI controls to those settings
|
||||
// Updating the config plugin if required
|
||||
void KWinDecorationModule::readConfig(const KConfigGroup & conf)
|
||||
{
|
||||
m_showTooltips = conf.readEntry("ShowToolTips", true);
|
||||
|
||||
// Find the corresponding decoration name to that of
|
||||
// the current plugin library name
|
||||
|
||||
QString libraryName = conf.readEntry("PluginLib", s_defaultPluginName);
|
||||
|
||||
if (libraryName.isEmpty()) {
|
||||
// Selected decoration doesn't exist, use the default
|
||||
libraryName = s_defaultPluginName;
|
||||
}
|
||||
|
||||
const int bsize = conf.readEntry("BorderSize", (int)BorderNormal);
|
||||
BorderSize borderSize = BorderNormal;
|
||||
if (bsize >= BorderTiny && bsize < BordersCount)
|
||||
borderSize = static_cast< BorderSize >(bsize);
|
||||
if (libraryName == "aurorae") {
|
||||
KConfig auroraeConfig("auroraerc");
|
||||
KConfigGroup group(&auroraeConfig, "Engine");
|
||||
const QString themeName = group.readEntry("ThemeName", "example-deco");
|
||||
const QString type = group.readEntry("EngineType", "aurorae");
|
||||
const QModelIndex index = m_proxyModel->mapFromSource(m_model->indexOfAuroraeName(themeName, type));
|
||||
if (index.isValid()) {
|
||||
m_listView->rootObject()->setProperty("currentIndex", index.row());
|
||||
}
|
||||
} else {
|
||||
const QModelIndex index = m_proxyModel->mapFromSource(m_model->indexOfLibrary(libraryName));
|
||||
if (index.isValid()) {
|
||||
m_model->setBorderSize(index, borderSize);
|
||||
m_listView->rootObject()->setProperty("currentIndex", index.row());
|
||||
}
|
||||
}
|
||||
|
||||
// Buttons tab
|
||||
// ============
|
||||
m_decorationButtons->setCustomPositions(conf.readEntry("CustomButtonPositions", false));
|
||||
// Menu and onAllDesktops buttons are default on LHS
|
||||
m_decorationButtons->setLeftButtons(KDecorationOptions::readDecorationButtons(conf, "ButtonsOnLeft",
|
||||
KDecorationOptions::defaultTitleButtonsLeft()));
|
||||
// Help, Minimize, Maximize and Close are default on RHS
|
||||
m_decorationButtons->setRightButtons(KDecorationOptions::readDecorationButtons(conf, "ButtonsOnRight",
|
||||
KDecorationOptions::defaultTitleButtonsRight()));
|
||||
if (m_configLoaded)
|
||||
m_model->changeButtons(m_decorationButtons);
|
||||
else {
|
||||
m_configLoaded = true;
|
||||
m_model->setButtons(m_decorationButtons->customPositions(), m_decorationButtons->leftButtons(), m_decorationButtons->rightButtons());
|
||||
}
|
||||
|
||||
emit KCModule::changed(false);
|
||||
}
|
||||
|
||||
|
||||
// Writes the selected user configuration to the kwin config file
|
||||
void KWinDecorationModule::writeConfig(KConfigGroup & conf)
|
||||
{
|
||||
const QModelIndex index = m_proxyModel->mapToSource(m_proxyModel->index(m_listView->rootObject()->property("currentIndex").toInt(), 0));
|
||||
const QString libName = m_model->data(index, DecorationModel::LibraryNameRole).toString();
|
||||
|
||||
// General settings
|
||||
conf.writeEntry("PluginLib", libName);
|
||||
conf.writeEntry("CustomButtonPositions", m_decorationButtons->customPositions());
|
||||
conf.writeEntry("ShowToolTips", m_showTooltips);
|
||||
|
||||
// Button settings
|
||||
KDecorationOptions::writeDecorationButtons(conf, "ButtonsOnLeft", m_decorationButtons->leftButtons());
|
||||
KDecorationOptions::writeDecorationButtons(conf, "ButtonsOnRight", m_decorationButtons->rightButtons());
|
||||
conf.writeEntry("BorderSize",
|
||||
static_cast<int>(m_model->data(index, DecorationModel::BorderSizeRole).toInt()));
|
||||
|
||||
if (m_model->data(index, DecorationModel::TypeRole).toInt() == DecorationModelData::AuroraeDecoration ||
|
||||
m_model->data(index, DecorationModel::TypeRole).toInt() == DecorationModelData::QmlDecoration) {
|
||||
KConfig auroraeConfig("auroraerc");
|
||||
KConfigGroup group(&auroraeConfig, "Engine");
|
||||
group.writeEntry("ThemeName", m_model->data(index, DecorationModel::AuroraeNameRole).toString());
|
||||
if (m_model->data(index, DecorationModel::TypeRole).toInt() == DecorationModelData::QmlDecoration) {
|
||||
group.writeEntry("EngineType", "qml");
|
||||
} else {
|
||||
group.deleteEntry("EngineType");
|
||||
}
|
||||
group.sync();
|
||||
}
|
||||
|
||||
// We saved, so tell kcmodule that there have been no new user changes made.
|
||||
emit KCModule::changed(false);
|
||||
}
|
||||
|
||||
|
||||
// Virutal functions required by KCModule
|
||||
void KWinDecorationModule::load()
|
||||
{
|
||||
const KConfigGroup config(kwinConfig, "Style");
|
||||
|
||||
// Reset by re-reading the config
|
||||
readConfig(config);
|
||||
}
|
||||
|
||||
|
||||
void KWinDecorationModule::save()
|
||||
{
|
||||
KConfigGroup config(kwinConfig, "Style");
|
||||
writeConfig(config);
|
||||
config.sync();
|
||||
|
||||
// Send signal to all kwin instances
|
||||
QDBusMessage message =
|
||||
QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig");
|
||||
QDBusConnection::sessionBus().send(message);
|
||||
}
|
||||
|
||||
|
||||
void KWinDecorationModule::defaults()
|
||||
{
|
||||
// Set the KDE defaults
|
||||
m_showTooltips = true;
|
||||
const QModelIndex index = m_proxyModel->mapFromSource(m_model->indexOfName(i18n("Oxygen")));
|
||||
if (index.isValid())
|
||||
m_listView->rootObject()->setProperty("currentIndex", index.row());
|
||||
|
||||
m_decorationButtons->resetToDefaults();
|
||||
|
||||
m_model->changeButtons(m_decorationButtons);
|
||||
|
||||
emit changed(true);
|
||||
}
|
||||
|
||||
QString KWinDecorationModule::quickHelp() const
|
||||
{
|
||||
return i18n("<h1>Window Manager Decoration</h1>"
|
||||
"<p>This module allows you to choose the window border decorations, "
|
||||
"as well as titlebar button positions and custom decoration options.</p>"
|
||||
"To choose a theme for your window decoration click on its name and apply your choice by clicking the \"Apply\" button below."
|
||||
" If you do not want to apply your choice you can click the \"Reset\" button to discard your changes."
|
||||
"<p>You can configure each theme. There are different options specific for each theme.</p>"
|
||||
"<p>On the \"Buttons\" tab check the \"Use custom titlebar button positions\" box "
|
||||
"and you can change the positions of the buttons to your liking.</p>");
|
||||
}
|
||||
|
||||
void KWinDecorationModule::slotConfigureButtons()
|
||||
{
|
||||
QPointer< KWinDecorationButtonsConfigDialog > configDialog = new KWinDecorationButtonsConfigDialog(m_decorationButtons, m_showTooltips, this);
|
||||
if (configDialog->exec() == QDialog::Accepted) {
|
||||
m_decorationButtons->setCustomPositions(configDialog->customPositions());
|
||||
m_showTooltips = configDialog->showTooltips();
|
||||
m_decorationButtons->setLeftButtons(configDialog->buttonsLeft());
|
||||
m_decorationButtons->setRightButtons(configDialog->buttonsRight());
|
||||
m_model->changeButtons(m_decorationButtons);
|
||||
emit changed(true);
|
||||
}
|
||||
|
||||
delete configDialog;
|
||||
}
|
||||
|
||||
void KWinDecorationModule::slotGHNSClicked()
|
||||
{
|
||||
QPointer<KNS3::DownloadDialog> downloadDialog = new KNS3::DownloadDialog("aurorae.knsrc", this);
|
||||
if (downloadDialog->exec() == QDialog::Accepted) {
|
||||
if (!downloadDialog->changedEntries().isEmpty()) {
|
||||
const QModelIndex index = m_proxyModel->mapToSource(m_proxyModel->index(m_listView->rootObject()->property("currentIndex").toInt(), 0));
|
||||
const QString libraryName = m_model->data(index, DecorationModel::LibraryNameRole).toString();
|
||||
bool aurorae = m_model->data(index, DecorationModel::TypeRole).toInt() == DecorationModelData::AuroraeDecoration;
|
||||
bool qml = m_model->data(index, DecorationModel::TypeRole).toInt() == DecorationModelData::QmlDecoration;
|
||||
const QString auroraeName = m_model->data(index, DecorationModel::AuroraeNameRole).toString();
|
||||
m_model->reload();
|
||||
if (aurorae) {
|
||||
const QModelIndex proxyIndex = m_proxyModel->mapFromSource(m_model->indexOfAuroraeName(auroraeName, "aurorae"));
|
||||
if (proxyIndex.isValid())
|
||||
m_listView->rootObject()->setProperty("currentIndex", proxyIndex.row());
|
||||
} else if (qml) {
|
||||
const QModelIndex proxyIndex = m_proxyModel->mapFromSource(m_model->indexOfAuroraeName(auroraeName, "qml"));
|
||||
if (proxyIndex.isValid())
|
||||
m_listView->rootObject()->setProperty("currentIndex", proxyIndex.row());
|
||||
} else {
|
||||
const QModelIndex proxyIndex = m_proxyModel->mapFromSource(m_model->indexOfLibrary(libraryName));
|
||||
if (proxyIndex.isValid())
|
||||
m_listView->rootObject()->setProperty("currentIndex", proxyIndex.row());
|
||||
}
|
||||
}
|
||||
}
|
||||
delete downloadDialog;
|
||||
}
|
||||
|
||||
void KWinDecorationModule::slotConfigureDecoration()
|
||||
{
|
||||
const QModelIndex index = m_proxyModel->mapToSource(m_proxyModel->index(m_listView->rootObject()->property("currentIndex").toInt(), 0));
|
||||
bool reload = false;
|
||||
if (index.data(DecorationModel::TypeRole).toInt() == DecorationModelData::AuroraeDecoration ||
|
||||
index.data(DecorationModel::TypeRole).toInt() == DecorationModelData::QmlDecoration) {
|
||||
QPointer<QDialog> dlg = new QDialog(this);
|
||||
dlg->setWindowTitle(i18n("Decoration Options"));
|
||||
KWinAuroraeConfigForm *form = new KWinAuroraeConfigForm(dlg);
|
||||
form->enableNoSideBorderSupport(index.data(DecorationModel::TypeRole).toInt() == DecorationModelData::QmlDecoration);
|
||||
dlg->setLayout(new QVBoxLayout);
|
||||
QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, dlg.data());
|
||||
connect(buttons, SIGNAL(accepted()), dlg, SLOT(accept()));
|
||||
connect(buttons, SIGNAL(rejected()), dlg, SLOT(reject()));
|
||||
dlg->layout()->addWidget(form);
|
||||
dlg->layout()->addWidget(buttons);
|
||||
|
||||
form->borderSizesCombo->setCurrentIndex(index.data(DecorationModel::BorderSizeRole).toInt());
|
||||
form->buttonSizesCombo->setCurrentIndex(index.data(DecorationModel::ButtonSizeRole).toInt());
|
||||
form->closeWindowsDoubleClick->setChecked(index.data(DecorationModel::CloseOnDblClickRole).toBool());
|
||||
form->doubleClickMessage->setCloseButtonVisible(true);
|
||||
form->doubleClickMessage->setText(i18n("Close by double clicking:\n To open the menu, keep the button pressed until it appears."));
|
||||
form->doubleClickMessage->setVisible(false);
|
||||
connect(form->closeWindowsDoubleClick, &QCheckBox::toggled, [form](bool toggled) {
|
||||
if (!toggled) {
|
||||
return;
|
||||
}
|
||||
form->doubleClickMessage->animatedShow();
|
||||
});
|
||||
// in case of QmlDecoration look for a config.ui in the package structure
|
||||
KConfigDialogManager *configManager = nullptr;
|
||||
if (index.data(DecorationModel::TypeRole).toInt() == DecorationModelData::QmlDecoration) {
|
||||
const QString packageName = index.data(DecorationModel::AuroraeNameRole).toString();
|
||||
const QString uiPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kwin/decorations/" + packageName + "/contents/ui/config.ui");
|
||||
const QString configPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kwin/decorations/" + packageName + "/contents/config/main.xml");
|
||||
if (!uiPath.isEmpty() && !configPath.isEmpty()) {
|
||||
// load the KConfigSkeleton
|
||||
QFile configFile(configPath);
|
||||
KSharedConfigPtr auroraeConfig = KSharedConfig::openConfig("auroraerc");
|
||||
KConfigGroup configGroup = auroraeConfig->group(packageName);
|
||||
KConfigLoader *skeleton = new KConfigLoader(configGroup, &configFile, dlg);
|
||||
// load the ui file
|
||||
m_translator->setTranslationDomain(index.data(DecorationModel::ConfigTranslationDomain).toString());
|
||||
QUiLoader *loader = new QUiLoader(dlg);
|
||||
loader->setLanguageChangeEnabled(true);
|
||||
QFile uiFile(uiPath);
|
||||
uiFile.open(QFile::ReadOnly);
|
||||
QWidget *customConfigForm = loader->load(&uiFile, form);
|
||||
m_translator->addContextToMonitor(customConfigForm->objectName());
|
||||
uiFile.close();
|
||||
form->layout()->addWidget(customConfigForm);
|
||||
// connect the ui file with the skeleton
|
||||
configManager = new KConfigDialogManager(customConfigForm, skeleton);
|
||||
configManager->updateWidgets();
|
||||
|
||||
// send a custom event to the translator to retranslate using our translator
|
||||
QEvent le(QEvent::LanguageChange);
|
||||
QCoreApplication::sendEvent(customConfigForm, &le);
|
||||
}
|
||||
}
|
||||
if (dlg->exec() == QDialog::Accepted) {
|
||||
m_model->setData(index, form->borderSizesCombo->currentIndex(), DecorationModel::BorderSizeRole);
|
||||
m_model->setData(index, form->buttonSizesCombo->currentIndex(), DecorationModel::ButtonSizeRole);
|
||||
m_model->setData(index, form->closeWindowsDoubleClick->isChecked(), DecorationModel::CloseOnDblClickRole);
|
||||
if (configManager && configManager->hasChanged()) {
|
||||
// we have a config manager and the settings changed
|
||||
configManager->updateSettings();
|
||||
m_model->notifyConfigChanged(index);
|
||||
}
|
||||
reload = true;
|
||||
}
|
||||
delete dlg;
|
||||
} else {
|
||||
QString name = index.data(DecorationModel::LibraryNameRole).toString();
|
||||
QList< QVariant > borderSizes = index.data(DecorationModel::BorderSizesRole).toList();
|
||||
const KDecorationDefines::BorderSize size =
|
||||
static_cast<KDecorationDefines::BorderSize>(index.data(DecorationModel::BorderSizeRole).toInt());
|
||||
QPointer< KWinDecorationConfigDialog > configDialog =
|
||||
new KWinDecorationConfigDialog(name, borderSizes, size, this);
|
||||
if (configDialog->exec() == QDialog::Accepted) {
|
||||
m_model->setData(index, configDialog->borderSize(), DecorationModel::BorderSizeRole);
|
||||
reload = true;
|
||||
}
|
||||
|
||||
delete configDialog;
|
||||
}
|
||||
if (reload) {
|
||||
save();
|
||||
}
|
||||
}
|
||||
|
||||
bool KWinDecorationModule::eventFilter(QObject *o, QEvent *e)
|
||||
{
|
||||
if (o == m_ui->decorationList) {
|
||||
if (e->type() == QEvent::Resize)
|
||||
updateScrollbarRange();
|
||||
else if (e->type() == QEvent::KeyPress) {
|
||||
int d = 0;
|
||||
const int currentRow = m_listView->rootObject()->property("currentIndex").toInt();
|
||||
const int key = static_cast<QKeyEvent*>(e)->key();
|
||||
switch (key) {
|
||||
case Qt::Key_Home:
|
||||
d = -currentRow;
|
||||
break;
|
||||
case Qt::Key_End:
|
||||
d = m_proxyModel->rowCount() - (1 + currentRow);
|
||||
break;
|
||||
case Qt::Key_Up:
|
||||
d = -1;
|
||||
break;
|
||||
case Qt::Key_Down:
|
||||
d = 1;
|
||||
break;
|
||||
case Qt::Key_PageUp:
|
||||
case Qt::Key_PageDown:
|
||||
d = 150;
|
||||
if (QObject *decoItem = m_listView->rootObject()->findChild<QObject*>("decorationItem")) {
|
||||
QVariant v = decoItem->property("height");
|
||||
if (v.isValid())
|
||||
d = v.toInt();
|
||||
}
|
||||
if (d > 0)
|
||||
d = qMax(m_ui->decorationList->height() / d, 1);
|
||||
if (key == Qt::Key_PageUp)
|
||||
d = -d;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (d) {
|
||||
d = qMin(qMax(0, currentRow + d), m_proxyModel->rowCount());
|
||||
m_listView->rootObject()->setProperty("currentIndex", d);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (m_ui->decorationList->viewport()) {
|
||||
if (e->type() == QEvent::Wheel) {
|
||||
return static_cast<QWheelEvent*>(e)->orientation() == Qt::Horizontal;
|
||||
}
|
||||
}
|
||||
return KCModule::eventFilter(o, e);
|
||||
}
|
||||
|
||||
void KWinDecorationModule::updateScrollbarRange()
|
||||
{
|
||||
m_ui->decorationList->verticalScrollBar()->blockSignals(true);
|
||||
const bool atMinimum = m_listView->rootObject()->property("atYBeginning").toBool();
|
||||
const int h = m_listView->rootObject()->property("contentHeight").toInt();
|
||||
const int y = atMinimum ? m_listView->rootObject()->property("contentY").toInt() : 0;
|
||||
m_ui->decorationList->verticalScrollBar()->setRange(y, y + h - m_ui->decorationList->height());
|
||||
m_ui->decorationList->verticalScrollBar()->setPageStep(m_ui->decorationList->verticalScrollBar()->maximum()/m_model->rowCount());
|
||||
m_ui->decorationList->verticalScrollBar()->blockSignals(false);
|
||||
}
|
||||
|
||||
void KWinDecorationModule::updateScrollbarValue()
|
||||
{
|
||||
const int v = m_listView->rootObject()->property("contentY").toInt();
|
||||
m_ui->decorationList->verticalScrollBar()->blockSignals(true); // skippig this will kill kinetic scrolling but the scrollwidth is too low
|
||||
m_ui->decorationList->verticalScrollBar()->setValue(v);
|
||||
m_ui->decorationList->verticalScrollBar()->blockSignals(false);
|
||||
}
|
||||
|
||||
void KWinDecorationModule::updateViewPosition(int v)
|
||||
{
|
||||
m_listView->rootObject()->setProperty("contentY", v);
|
||||
}
|
||||
|
||||
DecorationButtons::DecorationButtons(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_customPositions(false)
|
||||
, m_leftButtons()
|
||||
, m_rightButtons()
|
||||
{
|
||||
setLeftButtons(KDecorationOptions::defaultTitleButtonsLeft());
|
||||
setRightButtons(KDecorationOptions::defaultTitleButtonsRight());
|
||||
}
|
||||
|
||||
DecorationButtons::~DecorationButtons()
|
||||
{
|
||||
}
|
||||
|
||||
bool DecorationButtons::customPositions() const
|
||||
{
|
||||
return m_customPositions;
|
||||
}
|
||||
|
||||
const QList<KDecorationDefines::DecorationButton> &DecorationButtons::leftButtons() const
|
||||
{
|
||||
return m_leftButtons;
|
||||
}
|
||||
|
||||
const QList<KDecorationDefines::DecorationButton> &DecorationButtons::rightButtons() const
|
||||
{
|
||||
return m_rightButtons;
|
||||
}
|
||||
|
||||
void DecorationButtons::setCustomPositions(bool set)
|
||||
{
|
||||
if (m_customPositions == set) {
|
||||
return;
|
||||
}
|
||||
m_customPositions = set;
|
||||
emit customPositionsChanged();
|
||||
}
|
||||
|
||||
void DecorationButtons::setLeftButtons(const QList<DecorationButton> &leftButtons)
|
||||
{
|
||||
if (m_leftButtons == leftButtons) {
|
||||
return;
|
||||
}
|
||||
m_leftButtons = leftButtons;
|
||||
emit leftButtonsChanged();
|
||||
}
|
||||
|
||||
void DecorationButtons::setRightButtons(const QList<DecorationButton> &rightButtons)
|
||||
{
|
||||
if (m_rightButtons == rightButtons) {
|
||||
return;
|
||||
}
|
||||
m_rightButtons = rightButtons;
|
||||
emit rightButtonsChanged();
|
||||
}
|
||||
|
||||
void DecorationButtons::resetToDefaults()
|
||||
{
|
||||
setCustomPositions(false);
|
||||
setLeftButtons(KDecorationOptions::defaultTitleButtonsLeft());
|
||||
setRightButtons(KDecorationOptions::defaultTitleButtonsRight());
|
||||
}
|
||||
|
||||
} // namespace KWin
|
||||
|
||||
#include "kwindecoration.moc"
|
|
@ -1,143 +0,0 @@
|
|||
/*
|
||||
This is the new kwindecoration kcontrol module
|
||||
|
||||
Copyright (c) 2001
|
||||
Karol Szwed <gallium@kde.org>
|
||||
http://gallium.n3.net/
|
||||
Copyright 2009, 2010 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
Supports new kwin configuration plugins, and titlebar button position
|
||||
modification via dnd interface.
|
||||
|
||||
Based on original "kwintheme" (Window Borders)
|
||||
Copyright (C) 2001 Rik Hemsley (rikkus) <rik@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef KWINDECORATION_H
|
||||
#define KWINDECORATION_H
|
||||
|
||||
#include <kcmodule.h>
|
||||
#include <KSharedConfig>
|
||||
|
||||
#include <kdecoration.h>
|
||||
|
||||
#include "ui_decoration.h"
|
||||
|
||||
class QQuickView;
|
||||
class QSortFilterProxyModel;
|
||||
class KLocalizedTranslator;
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
class DecorationModel;
|
||||
|
||||
class KWinDecorationForm : public QWidget, public Ui::KWinDecorationForm
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit KWinDecorationForm(QWidget* parent);
|
||||
};
|
||||
|
||||
class DecorationButtons : public QObject, public KDecorationDefines
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool customButtonPositions READ customPositions WRITE setCustomPositions NOTIFY customPositionsChanged)
|
||||
public:
|
||||
explicit DecorationButtons(QObject *parent = nullptr);
|
||||
virtual ~DecorationButtons();
|
||||
|
||||
bool customPositions() const;
|
||||
const QList<DecorationButton> &leftButtons() const;
|
||||
const QList<DecorationButton> &rightButtons() const;
|
||||
|
||||
void setCustomPositions(bool set);
|
||||
void setLeftButtons(const QList<KDecorationDefines::DecorationButton> &buttons);
|
||||
void setRightButtons(const QList<KDecorationDefines::DecorationButton> &buttons);
|
||||
|
||||
public Q_SLOTS:
|
||||
void resetToDefaults();
|
||||
|
||||
Q_SIGNALS:
|
||||
void customPositionsChanged();
|
||||
void leftButtonsChanged();
|
||||
void rightButtonsChanged();
|
||||
|
||||
private:
|
||||
bool m_customPositions;
|
||||
QList<DecorationButton> m_leftButtons;
|
||||
QList<DecorationButton> m_rightButtons;
|
||||
};
|
||||
|
||||
class KWinDecorationModule : public KCModule, public KDecorationDefines
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
KWinDecorationModule(QWidget* parent, const QVariantList &);
|
||||
~KWinDecorationModule();
|
||||
|
||||
virtual void load();
|
||||
virtual void save();
|
||||
virtual void defaults();
|
||||
|
||||
QString quickHelp() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void pluginLoad(const KConfigGroup& conf);
|
||||
void pluginSave(KConfigGroup &conf);
|
||||
void pluginDefaults();
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *o, QEvent *e);
|
||||
virtual void showEvent(QShowEvent *ev);
|
||||
|
||||
protected Q_SLOTS:
|
||||
// Allows us to turn "save" on
|
||||
void slotSelectionChanged();
|
||||
void slotConfigureButtons();
|
||||
void slotGHNSClicked();
|
||||
void slotConfigureDecoration();
|
||||
|
||||
private:
|
||||
void init();
|
||||
void readConfig(const KConfigGroup& conf);
|
||||
void writeConfig(KConfigGroup &conf);
|
||||
private Q_SLOTS:
|
||||
void updateScrollbarRange();
|
||||
void updateScrollbarValue();
|
||||
void updateViewPosition(int v);
|
||||
private:
|
||||
KSharedConfigPtr kwinConfig;
|
||||
|
||||
KWinDecorationForm* m_ui;
|
||||
bool m_showTooltips;
|
||||
|
||||
DecorationModel* m_model;
|
||||
QSortFilterProxyModel* m_proxyModel;
|
||||
bool m_configLoaded;
|
||||
DecorationButtons *m_decorationButtons;
|
||||
|
||||
QScopedPointer<QQuickView> m_listView;
|
||||
|
||||
KLocalizedTranslator *m_translator;
|
||||
};
|
||||
|
||||
} //namespace
|
||||
|
||||
#endif
|
|
@ -1,630 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (c) 2003 Lubos Lunak <l.lunak@kde.org>
|
||||
* Copyright (c) 2013 Martin Gräßlin <mgraesslin@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "preview.h"
|
||||
|
||||
#include <KLocalizedString>
|
||||
#include <kconfig.h>
|
||||
#include <QApplication>
|
||||
#include <QPainter>
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include <kdecorationfactory.h>
|
||||
|
||||
static const int SMALL_OFFSET = 10;
|
||||
static const int LARGE_OFFSET = 40;
|
||||
|
||||
PreviewItem::PreviewItem(QQuickItem *parent)
|
||||
: QQuickPaintedItem(parent)
|
||||
, m_plugins(new KDecorationPreviewPlugins(KSharedConfig::openConfig(QStringLiteral("kwinrc"))))
|
||||
, m_activeBridge(new KDecorationPreviewBridge(this, true))
|
||||
, m_inactiveBridge(new KDecorationPreviewBridge(this, false))
|
||||
, m_activeDecoration(nullptr)
|
||||
, m_inactiveDecoration(nullptr)
|
||||
, m_activeEntered(nullptr)
|
||||
, m_inactiveEntered(nullptr)
|
||||
{
|
||||
setFlag(ItemHasContents, true);
|
||||
setAcceptHoverEvents(true);
|
||||
connect(this, &PreviewItem::libraryChanged, this, &PreviewItem::loadDecorationPlugin);
|
||||
}
|
||||
|
||||
PreviewItem::~PreviewItem()
|
||||
{
|
||||
delete m_activeDecoration;
|
||||
delete m_inactiveDecoration;
|
||||
}
|
||||
|
||||
void PreviewItem::setLibraryName(const QString &library)
|
||||
{
|
||||
if (library == m_libraryName || library.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
m_libraryName = library;
|
||||
emit libraryChanged();
|
||||
}
|
||||
|
||||
void PreviewItem::loadDecorationPlugin()
|
||||
{
|
||||
const bool loaded = m_plugins->loadPlugin(m_libraryName);
|
||||
if (!loaded) {
|
||||
return;
|
||||
}
|
||||
m_plugins->destroyPreviousPlugin();
|
||||
connect(m_plugins->factory(), &KDecorationFactory::recreateDecorations,
|
||||
this, &PreviewItem::recreateDecorations, Qt::QueuedConnection);
|
||||
recreateDecorations();
|
||||
}
|
||||
|
||||
void PreviewItem::recreateDecorations()
|
||||
{
|
||||
delete m_activeDecoration;
|
||||
delete m_inactiveDecoration;
|
||||
m_activeEntered = nullptr;
|
||||
m_inactiveEntered = nullptr;
|
||||
m_activeDecoration = m_plugins->createDecoration(m_activeBridge.data());
|
||||
m_inactiveDecoration = m_plugins->createDecoration(m_inactiveBridge.data());
|
||||
|
||||
if (m_activeDecoration) {
|
||||
m_activeDecoration->init();
|
||||
if (m_activeDecoration->widget()) {
|
||||
m_activeDecoration->widget()->installEventFilter(this);
|
||||
}
|
||||
}
|
||||
if (m_inactiveDecoration) {
|
||||
m_inactiveDecoration->init();
|
||||
if (m_inactiveDecoration->widget()) {
|
||||
m_inactiveDecoration->widget()->installEventFilter(this);
|
||||
}
|
||||
}
|
||||
updatePreview();
|
||||
}
|
||||
|
||||
void PreviewItem::geometryChanged(const QRectF& newGeometry, const QRectF& oldGeometry)
|
||||
{
|
||||
QQuickPaintedItem::geometryChanged(newGeometry, oldGeometry);
|
||||
updatePreview();
|
||||
}
|
||||
|
||||
void PreviewItem::updatePreview()
|
||||
{
|
||||
if (width() == 0 && height() == 0) {
|
||||
return;
|
||||
}
|
||||
if (!m_activeDecoration && !m_inactiveDecoration) {
|
||||
return;
|
||||
}
|
||||
const QSize size(width() - 50, height() - 50);
|
||||
updateSize(size, m_activeDecoration, m_activeBuffer);
|
||||
updateSize(size, m_inactiveDecoration, m_inactiveBuffer);
|
||||
|
||||
render(&m_activeBuffer, m_activeDecoration);
|
||||
render(&m_inactiveBuffer, m_inactiveDecoration);
|
||||
update();
|
||||
}
|
||||
|
||||
void PreviewItem::updateSize(const QSize &baseSize, KDecoration *decoration, QImage &buffer)
|
||||
{
|
||||
if (!decoration) {
|
||||
return;
|
||||
}
|
||||
int left, right, top, bottom;
|
||||
left = right = top = bottom = 0;
|
||||
decoration->padding(left, right, top, bottom);
|
||||
const QSize size = baseSize + QSize(left + right, top + bottom);
|
||||
if (decoration->geometry().size() != size) {
|
||||
decoration->resize(size);
|
||||
}
|
||||
if (buffer.isNull() || buffer.size() != size) {
|
||||
buffer = QImage(size, QImage::Format_ARGB32_Premultiplied);
|
||||
}
|
||||
}
|
||||
|
||||
void PreviewItem::render(QImage* image, KDecoration* decoration)
|
||||
{
|
||||
image->fill(Qt::transparent);
|
||||
decoration->render(image, QRegion());
|
||||
}
|
||||
|
||||
void PreviewItem::paint(QPainter *painter)
|
||||
{
|
||||
int paddingLeft, paddingRigth, paddingTop, paddingBottom;
|
||||
paddingLeft = paddingRigth = paddingTop = paddingBottom = 0;
|
||||
if (m_inactiveDecoration) {
|
||||
m_inactiveDecoration->padding(paddingLeft, paddingRigth, paddingTop, paddingBottom);
|
||||
}
|
||||
|
||||
painter->drawImage(LARGE_OFFSET - paddingLeft, SMALL_OFFSET - paddingTop, m_inactiveBuffer);
|
||||
|
||||
paddingLeft = paddingRigth = paddingTop = paddingBottom = 0;
|
||||
if (m_activeDecoration) {
|
||||
m_activeDecoration->padding(paddingLeft, paddingRigth, paddingTop, paddingBottom);
|
||||
}
|
||||
painter->drawImage(SMALL_OFFSET - paddingLeft, LARGE_OFFSET - paddingTop, m_activeBuffer);
|
||||
}
|
||||
|
||||
void PreviewItem::hoverMoveEvent(QHoverEvent* event)
|
||||
{
|
||||
QQuickItem::hoverMoveEvent(event);
|
||||
const int w = width() - LARGE_OFFSET - SMALL_OFFSET;
|
||||
const int h = height() - LARGE_OFFSET - SMALL_OFFSET;
|
||||
forwardMoveEvent(event, QRect(SMALL_OFFSET, LARGE_OFFSET, w, h), m_activeDecoration, &m_activeEntered);
|
||||
forwardMoveEvent(event, QRect(LARGE_OFFSET, SMALL_OFFSET, w, h), m_inactiveDecoration, &m_inactiveEntered);
|
||||
}
|
||||
|
||||
void PreviewItem::forwardMoveEvent(QHoverEvent *event, const QRect &geo, KDecoration *deco, QWidget **entered)
|
||||
{
|
||||
auto leaveEvent = [](QWidget **widget) {
|
||||
if (!(*widget)) {
|
||||
return;
|
||||
}
|
||||
// send old one a leave event
|
||||
QEvent leave(QEvent::Leave);
|
||||
QApplication::sendEvent(*widget, &leave);
|
||||
*widget = nullptr;
|
||||
};
|
||||
if (geo.contains(event->pos()) && deco && deco->widget()) {
|
||||
int paddingLeft, paddingRigth, paddingTop, paddingBottom;
|
||||
paddingLeft = paddingRigth = paddingTop = paddingBottom = 0;
|
||||
deco->padding(paddingLeft, paddingRigth, paddingTop, paddingBottom);
|
||||
const QPoint widgetPos = event->pos() - geo.topLeft() + QPoint(paddingLeft, paddingTop);
|
||||
if (QWidget *widget = deco->widget()->childAt(widgetPos)) {
|
||||
if (widget != *entered) {
|
||||
leaveEvent(entered);
|
||||
// send enter event
|
||||
*entered = widget;
|
||||
QEnterEvent enter(widgetPos - widget->geometry().topLeft(), widgetPos, event->pos());
|
||||
QApplication::sendEvent(*entered, &enter);
|
||||
}
|
||||
} else {
|
||||
leaveEvent(entered);
|
||||
}
|
||||
} else {
|
||||
leaveEvent(entered);
|
||||
}
|
||||
}
|
||||
|
||||
void PreviewItem::updateDecoration(KDecorationPreviewBridge *bridge)
|
||||
{
|
||||
if (bridge == m_activeBridge.data()) {
|
||||
render(&m_activeBuffer, m_activeDecoration);
|
||||
} else if (bridge == m_inactiveBridge.data()) {
|
||||
render(&m_inactiveBuffer, m_inactiveDecoration);
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
KDecorationPreview::KDecorationPreview(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
bridge[Active] = new KDecorationPreviewBridge(this, true);
|
||||
bridge[Inactive] = new KDecorationPreviewBridge(this, false);
|
||||
|
||||
deco[Active] = deco[Inactive] = NULL;
|
||||
|
||||
setMinimumSize(100, 100);
|
||||
}
|
||||
|
||||
KDecorationPreview::~KDecorationPreview()
|
||||
{
|
||||
for (int i = 0; i < NumWindows; i++) {
|
||||
delete deco[i];
|
||||
delete bridge[i];
|
||||
}
|
||||
}
|
||||
|
||||
void KDecorationPreview::disablePreview()
|
||||
{
|
||||
delete deco[Active];
|
||||
delete deco[Inactive];
|
||||
deco[Active] = deco[Inactive] = NULL;
|
||||
}
|
||||
|
||||
KDecorationFactory *KDecorationPreview::factory() const
|
||||
{
|
||||
return deco[Active] ? deco[Active]->factory() : 0;
|
||||
}
|
||||
|
||||
QRect KDecorationPreview::windowGeometry(bool active) const
|
||||
{
|
||||
QWidget *widget = active ? deco[Active]->widget() : deco[Inactive]->widget();
|
||||
return widget->geometry();
|
||||
}
|
||||
|
||||
QRegion KDecorationPreview::unobscuredRegion(bool active, const QRegion& r) const
|
||||
{
|
||||
Q_UNUSED(active)
|
||||
return r;
|
||||
}
|
||||
|
||||
KDecorationPreviewBridge::KDecorationPreviewBridge(KDecorationPreview* p, bool a)
|
||||
: preview(p)
|
||||
, m_previewItem(nullptr)
|
||||
, active(a)
|
||||
{
|
||||
}
|
||||
|
||||
KDecorationPreviewBridge::KDecorationPreviewBridge(PreviewItem *p, bool a)
|
||||
: preview(nullptr)
|
||||
, m_previewItem(p)
|
||||
, active(a)
|
||||
{
|
||||
}
|
||||
|
||||
Qt::WindowFlags KDecorationPreviewBridge::initialWFlags() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool KDecorationPreviewBridge::isActive() const
|
||||
{
|
||||
return active;
|
||||
}
|
||||
|
||||
bool KDecorationPreviewBridge::isCloseable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KDecorationPreviewBridge::isMaximizable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
KDecoration::MaximizeMode KDecorationPreviewBridge::maximizeMode() const
|
||||
{
|
||||
return KDecoration::MaximizeRestore;
|
||||
}
|
||||
|
||||
KDecoration::QuickTileMode KDecorationPreviewBridge::quickTileMode() const
|
||||
{
|
||||
return KDecoration::QuickTileNone;
|
||||
}
|
||||
|
||||
bool KDecorationPreviewBridge::isMinimizable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KDecorationPreviewBridge::providesContextHelp() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int KDecorationPreviewBridge::desktop() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool KDecorationPreviewBridge::isOnAllDesktopsAvailable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KDecorationPreviewBridge::isModal() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool KDecorationPreviewBridge::isShadeable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KDecorationPreviewBridge::isShade() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool KDecorationPreviewBridge::isSetShade() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool KDecorationPreviewBridge::keepAbove() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool KDecorationPreviewBridge::keepBelow() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool KDecorationPreviewBridge::isMovable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KDecorationPreviewBridge::isResizable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
NET::WindowType KDecorationPreviewBridge::windowType(unsigned long) const
|
||||
{
|
||||
return NET::Normal;
|
||||
}
|
||||
|
||||
QIcon KDecorationPreviewBridge::icon() const
|
||||
{
|
||||
return QIcon::fromTheme(QStringLiteral("xorg"));
|
||||
}
|
||||
|
||||
QString KDecorationPreviewBridge::caption() const
|
||||
{
|
||||
return active ? i18n("Active Window") : i18n("Inactive Window");
|
||||
}
|
||||
|
||||
void KDecorationPreviewBridge::processMousePressEvent(QMouseEvent*)
|
||||
{
|
||||
}
|
||||
|
||||
void KDecorationPreviewBridge::showWindowMenu(const QRect &)
|
||||
{
|
||||
}
|
||||
|
||||
void KDecorationPreviewBridge::showWindowMenu(const QPoint &)
|
||||
{
|
||||
}
|
||||
|
||||
void KDecorationPreviewBridge::showApplicationMenu(const QPoint &)
|
||||
{
|
||||
}
|
||||
|
||||
bool KDecorationPreviewBridge::menuAvailable() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void KDecorationPreviewBridge::performWindowOperation(WindowOperation)
|
||||
{
|
||||
}
|
||||
|
||||
void KDecorationPreviewBridge::setMask(const QRegion& reg, int mode)
|
||||
{
|
||||
Q_UNUSED(reg)
|
||||
Q_UNUSED(mode)
|
||||
}
|
||||
|
||||
bool KDecorationPreviewBridge::isPreview() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
QRect KDecorationPreviewBridge::geometry() const
|
||||
{
|
||||
if (preview) {
|
||||
return preview->windowGeometry(active);
|
||||
}
|
||||
return QRect();
|
||||
}
|
||||
|
||||
QRect KDecorationPreviewBridge::iconGeometry() const
|
||||
{
|
||||
return QRect();
|
||||
}
|
||||
|
||||
QRegion KDecorationPreviewBridge::unobscuredRegion(const QRegion& r) const
|
||||
{
|
||||
return preview->unobscuredRegion(active, r);
|
||||
}
|
||||
|
||||
WId KDecorationPreviewBridge::windowId() const
|
||||
{
|
||||
return 0; // no decorated window
|
||||
}
|
||||
|
||||
void KDecorationPreviewBridge::closeWindow()
|
||||
{
|
||||
}
|
||||
|
||||
void KDecorationPreviewBridge::maximize(MaximizeMode)
|
||||
{
|
||||
}
|
||||
|
||||
void KDecorationPreviewBridge::minimize()
|
||||
{
|
||||
}
|
||||
|
||||
void KDecorationPreviewBridge::showContextHelp()
|
||||
{
|
||||
}
|
||||
|
||||
void KDecorationPreviewBridge::setDesktop(int)
|
||||
{
|
||||
}
|
||||
|
||||
void KDecorationPreviewBridge::titlebarDblClickOperation()
|
||||
{
|
||||
}
|
||||
|
||||
void KDecorationPreviewBridge::titlebarMouseWheelOperation(int)
|
||||
{
|
||||
}
|
||||
|
||||
void KDecorationPreviewBridge::setShade(bool)
|
||||
{
|
||||
}
|
||||
|
||||
void KDecorationPreviewBridge::setKeepAbove(bool)
|
||||
{
|
||||
}
|
||||
|
||||
void KDecorationPreviewBridge::setKeepBelow(bool)
|
||||
{
|
||||
}
|
||||
|
||||
int KDecorationPreviewBridge::currentDesktop() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void KDecorationPreviewBridge::grabXServer(bool)
|
||||
{
|
||||
}
|
||||
|
||||
bool KDecorationPreviewBridge::compositingActive() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
QRect KDecorationPreviewBridge::transparentRect() const
|
||||
{
|
||||
return QRect();
|
||||
}
|
||||
|
||||
// Window tabbing
|
||||
|
||||
int KDecorationPreviewBridge::tabCount() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
QString KDecorationPreviewBridge::caption(int) const
|
||||
{
|
||||
return active ? "Active Window" : "Inactive Window";
|
||||
}
|
||||
|
||||
QIcon KDecorationPreviewBridge::icon(int) const
|
||||
{
|
||||
return icon();
|
||||
}
|
||||
|
||||
long KDecorationPreviewBridge::tabId(int) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
long KDecorationPreviewBridge::currentTabId() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void KDecorationPreviewBridge::setCurrentTab(long)
|
||||
{
|
||||
}
|
||||
|
||||
void KDecorationPreviewBridge::tab_A_before_B(long, long)
|
||||
{
|
||||
}
|
||||
|
||||
void KDecorationPreviewBridge::tab_A_behind_B(long, long)
|
||||
{
|
||||
}
|
||||
|
||||
void KDecorationPreviewBridge::untab(long, const QRect&)
|
||||
{
|
||||
}
|
||||
|
||||
void KDecorationPreviewBridge::closeTab(long)
|
||||
{
|
||||
}
|
||||
|
||||
void KDecorationPreviewBridge::closeTabGroup()
|
||||
{
|
||||
}
|
||||
|
||||
void KDecorationPreviewBridge::showWindowMenu(const QPoint &, long)
|
||||
{
|
||||
}
|
||||
|
||||
void KDecorationPreviewBridge::update(const QRegion&)
|
||||
{
|
||||
if (m_previewItem) {
|
||||
// call update
|
||||
m_previewItem->updateDecoration(this);
|
||||
}
|
||||
}
|
||||
|
||||
KDecoration::WindowOperation KDecorationPreviewBridge::buttonToWindowOperation(Qt::MouseButtons)
|
||||
{
|
||||
return KDecoration::NoOp;
|
||||
}
|
||||
|
||||
QPalette KDecorationPreviewBridge::palette() const
|
||||
{
|
||||
return QApplication::palette();
|
||||
}
|
||||
|
||||
KDecorationPreviewOptions::KDecorationPreviewOptions()
|
||||
{
|
||||
customBorderSize = BordersCount; // invalid
|
||||
customButtonsChanged = false; // invalid
|
||||
customButtons = true;
|
||||
customTitleButtonsLeft.clear(); // invalid
|
||||
customTitleButtonsRight.clear(); // invalid
|
||||
updateSettings();
|
||||
}
|
||||
|
||||
KDecorationPreviewOptions::~KDecorationPreviewOptions()
|
||||
{
|
||||
}
|
||||
|
||||
void KDecorationPreviewOptions::updateSettings()
|
||||
{
|
||||
KConfig cfg("kwinrc");
|
||||
KDecorationOptions::updateSettings(&cfg);
|
||||
|
||||
// set custom border size/buttons
|
||||
if (customBorderSize != BordersCount)
|
||||
setBorderSize(customBorderSize);
|
||||
if (customButtonsChanged)
|
||||
setCustomButtonPositions(customButtons);
|
||||
if (customButtons) {
|
||||
if (!customTitleButtonsLeft.isEmpty())
|
||||
setTitleButtonsLeft(customTitleButtonsLeft);
|
||||
if (!customTitleButtonsRight.isEmpty())
|
||||
setTitleButtonsRight(customTitleButtonsRight);
|
||||
} else {
|
||||
setTitleButtonsLeft(KDecorationOptions::defaultTitleButtonsLeft());
|
||||
setTitleButtonsRight(KDecorationOptions::defaultTitleButtonsRight());
|
||||
}
|
||||
}
|
||||
|
||||
void KDecorationPreviewOptions::setCustomBorderSize(BorderSize size)
|
||||
{
|
||||
customBorderSize = size;
|
||||
|
||||
updateSettings();
|
||||
}
|
||||
|
||||
void KDecorationPreviewOptions::setCustomTitleButtonsEnabled(bool enabled)
|
||||
{
|
||||
customButtonsChanged = true;
|
||||
customButtons = enabled;
|
||||
|
||||
updateSettings();
|
||||
}
|
||||
|
||||
void KDecorationPreviewOptions::setCustomTitleButtons(const QList<DecorationButton> &left, const QList<DecorationButton> &right)
|
||||
{
|
||||
customTitleButtonsLeft = left;
|
||||
customTitleButtonsRight = right;
|
||||
|
||||
updateSettings();
|
||||
}
|
||||
|
||||
bool KDecorationPreviewPlugins::provides(Requirement)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#include "preview.moc"
|
|
@ -1,210 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (c) 2003 Lubos Lunak <l.lunak@kde.org>
|
||||
* Copyright (c) 2013 Martin Gräßlin <mgraesslin@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef KWINDECORATION_PREVIEW_H
|
||||
#define KWINDECORATION_PREVIEW_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QQuickPaintedItem>
|
||||
#include <kdecoration.h>
|
||||
#include <kdecorationbridge.h>
|
||||
#include <kdecoration_plugins_p.h>
|
||||
|
||||
class KDecorationPreviewBridge;
|
||||
class KDecorationPreviewOptions;
|
||||
class QMouseEvent;
|
||||
|
||||
class PreviewItem : public QQuickPaintedItem
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString library READ libraryName WRITE setLibraryName NOTIFY libraryChanged)
|
||||
public:
|
||||
PreviewItem(QQuickItem *parent = nullptr);
|
||||
virtual ~PreviewItem();
|
||||
virtual void paint(QPainter *painter);
|
||||
|
||||
void setLibraryName(const QString &library);
|
||||
const QString &libraryName() const {
|
||||
return m_libraryName;
|
||||
}
|
||||
void updateDecoration(KDecorationPreviewBridge *bridge);
|
||||
|
||||
Q_SIGNALS:
|
||||
void libraryChanged();
|
||||
|
||||
protected:
|
||||
virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
|
||||
virtual void hoverMoveEvent(QHoverEvent *event);
|
||||
|
||||
private Q_SLOTS:
|
||||
void loadDecorationPlugin();
|
||||
void recreateDecorations();
|
||||
|
||||
private:
|
||||
void updatePreview();
|
||||
void updateSize(const QSize &size, KDecoration *decoration, QImage &buffer);
|
||||
void render(QImage *image, KDecoration *decoration);
|
||||
void forwardMoveEvent(QHoverEvent *event, const QRect &geo, KDecoration *deco, QWidget **entered);
|
||||
QScopedPointer<KDecorationPlugins> m_plugins;
|
||||
QScopedPointer<KDecorationPreviewBridge> m_activeBridge;
|
||||
QScopedPointer<KDecorationPreviewBridge> m_inactiveBridge;
|
||||
KDecoration *m_activeDecoration;
|
||||
KDecoration *m_inactiveDecoration;
|
||||
QWidget *m_activeEntered;
|
||||
QWidget *m_inactiveEntered;
|
||||
QString m_libraryName;
|
||||
QImage m_activeBuffer;
|
||||
QImage m_inactiveBuffer;
|
||||
};
|
||||
|
||||
class KDecorationPreview
|
||||
: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
// Note: Windows can't be added or removed without making changes to
|
||||
// the code, since parts of it assume there's just an active
|
||||
// and an inactive window.
|
||||
enum Windows { Inactive = 0, Active, NumWindows };
|
||||
|
||||
explicit KDecorationPreview(QWidget* parent = nullptr);
|
||||
virtual ~KDecorationPreview();
|
||||
void disablePreview();
|
||||
KDecorationFactory *factory() const;
|
||||
QRegion unobscuredRegion(bool, const QRegion&) const;
|
||||
QRect windowGeometry(bool) const;
|
||||
private:
|
||||
KDecorationPreviewBridge* bridge[NumWindows];
|
||||
KDecoration* deco[NumWindows];
|
||||
};
|
||||
|
||||
class KDecorationPreviewBridge
|
||||
: public KDecorationBridge
|
||||
{
|
||||
public:
|
||||
KDecorationPreviewBridge(KDecorationPreview* preview, bool active);
|
||||
KDecorationPreviewBridge(PreviewItem* preview, bool active);
|
||||
virtual bool isActive() const override;
|
||||
virtual bool isCloseable() const override;
|
||||
virtual bool isMaximizable() const override;
|
||||
virtual MaximizeMode maximizeMode() const override;
|
||||
virtual QuickTileMode quickTileMode() const override;
|
||||
virtual bool isMinimizable() const override;
|
||||
virtual bool providesContextHelp() const override;
|
||||
virtual int desktop() const override;
|
||||
bool isOnAllDesktopsAvailable() const override;
|
||||
virtual bool isModal() const override;
|
||||
virtual bool isShadeable() const override;
|
||||
virtual bool isShade() const override;
|
||||
virtual bool isSetShade() const override;
|
||||
virtual bool keepAbove() const override;
|
||||
virtual bool keepBelow() const override;
|
||||
virtual bool isMovable() const override;
|
||||
virtual bool isResizable() const override;
|
||||
virtual NET::WindowType windowType(unsigned long supported_types) const override;
|
||||
virtual QIcon icon() const override;
|
||||
virtual QString caption() const override;
|
||||
virtual void processMousePressEvent(QMouseEvent*) override;
|
||||
virtual void showWindowMenu(const QRect &) override;
|
||||
virtual void showWindowMenu(const QPoint &) override;
|
||||
virtual void showApplicationMenu(const QPoint &) override;
|
||||
virtual bool menuAvailable() const override;
|
||||
virtual void performWindowOperation(WindowOperation) override;
|
||||
virtual void setMask(const QRegion&, int) override;
|
||||
virtual bool isPreview() const override;
|
||||
virtual QRect geometry() const override;
|
||||
virtual QRect iconGeometry() const override;
|
||||
virtual QRegion unobscuredRegion(const QRegion& r) const override;
|
||||
virtual WId windowId() const override;
|
||||
virtual void closeWindow() override;
|
||||
virtual void maximize(MaximizeMode mode) override;
|
||||
virtual void minimize() override;
|
||||
virtual void showContextHelp() override;
|
||||
virtual void setDesktop(int desktop) override;
|
||||
virtual void titlebarDblClickOperation() override;
|
||||
virtual void titlebarMouseWheelOperation(int delta) override;
|
||||
virtual void setShade(bool set) override;
|
||||
virtual void setKeepAbove(bool) override;
|
||||
virtual void setKeepBelow(bool) override;
|
||||
virtual int currentDesktop() const override;
|
||||
virtual Qt::WindowFlags initialWFlags() const override;
|
||||
virtual void grabXServer(bool grab) override;
|
||||
|
||||
virtual bool compositingActive() const override;
|
||||
virtual QRect transparentRect() const override;
|
||||
|
||||
virtual void update(const QRegion ®ion) override;
|
||||
virtual QPalette palette() const override;
|
||||
|
||||
// Window tabbing
|
||||
virtual QString caption(int idx) const override;
|
||||
virtual void closeTab(long id) override;
|
||||
virtual void closeTabGroup() override;
|
||||
virtual long currentTabId() const override;
|
||||
virtual QIcon icon(int idx) const override;
|
||||
virtual void setCurrentTab(long id) override;
|
||||
virtual void showWindowMenu(const QPoint &, long id) override;
|
||||
virtual void tab_A_before_B(long A, long B) override;
|
||||
virtual void tab_A_behind_B(long A, long B) override;
|
||||
virtual int tabCount() const override;
|
||||
virtual long tabId(int idx) const override;
|
||||
virtual void untab(long id, const QRect& newGeom) override;
|
||||
virtual WindowOperation buttonToWindowOperation(Qt::MouseButtons button) override;
|
||||
|
||||
private:
|
||||
KDecorationPreview* preview;
|
||||
PreviewItem *m_previewItem;
|
||||
bool active;
|
||||
};
|
||||
|
||||
class KDecorationPreviewOptions
|
||||
: public KDecorationOptions
|
||||
{
|
||||
public:
|
||||
KDecorationPreviewOptions();
|
||||
virtual ~KDecorationPreviewOptions();
|
||||
void updateSettings();
|
||||
|
||||
void setCustomBorderSize(BorderSize size);
|
||||
void setCustomTitleButtonsEnabled(bool enabled);
|
||||
void setCustomTitleButtons(const QList<DecorationButton> &left, const QList<DecorationButton> &right);
|
||||
|
||||
private:
|
||||
BorderSize customBorderSize;
|
||||
bool customButtonsChanged;
|
||||
bool customButtons;
|
||||
QList<DecorationButton> customTitleButtonsLeft;
|
||||
QList<DecorationButton> customTitleButtonsRight;
|
||||
};
|
||||
|
||||
class KDecorationPreviewPlugins
|
||||
: public KDecorationPlugins
|
||||
{
|
||||
public:
|
||||
explicit KDecorationPreviewPlugins(const KSharedConfigPtr &cfg);
|
||||
virtual bool provides(Requirement);
|
||||
};
|
||||
|
||||
inline KDecorationPreviewPlugins::KDecorationPreviewPlugins(const KSharedConfigPtr &cfg)
|
||||
: KDecorationPlugins(cfg)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,73 +0,0 @@
|
|||
/********************************************************************
|
||||
Copyright (C) 2012 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
import QtQuick 2.0
|
||||
|
||||
Item {
|
||||
property alias active: decoration.active
|
||||
property alias source: auroraeLoader.source
|
||||
QtObject {
|
||||
signal configChanged
|
||||
id: decoration
|
||||
property bool active: false
|
||||
property string caption: display
|
||||
property int desktop: 1
|
||||
property variant icon: "xorg"
|
||||
property bool closeable: true
|
||||
property bool maximizeable: true
|
||||
property bool minimizeable: true
|
||||
property bool modal: false
|
||||
property bool moveable: true
|
||||
property bool onAllDesktops: false
|
||||
property bool preview: true
|
||||
property bool resizeable: true
|
||||
property bool setShade: false
|
||||
property bool shade: false
|
||||
property bool shadeable: false
|
||||
property bool keepAbove: false
|
||||
property bool keepBelow: false
|
||||
property bool maximized: false
|
||||
property bool providesContextHelp: true
|
||||
property bool appMenu: true
|
||||
property string leftButtons: "MS"
|
||||
property string rightButtons: "HIA__X"
|
||||
function titleMouseMoved() {}
|
||||
function readConfig(key, defaultValue) {
|
||||
if (key == "BorderSize") {
|
||||
return borderSize;
|
||||
} else if (key == "ButtonSize") {
|
||||
return buttonSize;
|
||||
} else {
|
||||
return decorationBaseModel.readConfig(auroraeThemeName, key, defaultValue);
|
||||
}
|
||||
}
|
||||
// just to not cause warnings
|
||||
signal buttonsChanged()
|
||||
signal fontChanged()
|
||||
}
|
||||
Loader {
|
||||
id: auroraeLoader
|
||||
anchors.fill: parent
|
||||
}
|
||||
Connections {
|
||||
target: decorationBaseModel
|
||||
onConfigChanged: {
|
||||
if (auroraeThemeName == themeName) {
|
||||
decoration.configChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
/********************************************************************
|
||||
Copyright (C) 2012 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
import QtQuick 2.0
|
||||
import org.kde.kwin.aurorae 0.1
|
||||
|
||||
Item {
|
||||
id: aurorae
|
||||
AuroraeTheme {
|
||||
id: auroraeTheme
|
||||
Component.onCompleted: {
|
||||
auroraeTheme.loadTheme(auroraeThemeName);
|
||||
inactiveAurorae.source = auroraeSource;
|
||||
activeAurorae.source = auroraeSource;
|
||||
}
|
||||
}
|
||||
AuroraeDecoration {
|
||||
id: inactiveAurorae
|
||||
active: false
|
||||
anchors {
|
||||
fill: parent
|
||||
leftMargin: 40 - auroraeTheme.paddingLeft
|
||||
rightMargin: 10 - auroraeTheme.paddingRight
|
||||
topMargin: 10 - auroraeTheme.paddingTop
|
||||
bottomMargin: 40 - auroraeTheme.paddingBottom
|
||||
}
|
||||
}
|
||||
AuroraeDecoration {
|
||||
id: activeAurorae
|
||||
active: true
|
||||
anchors {
|
||||
fill: parent
|
||||
leftMargin: 10 - auroraeTheme.paddingLeft
|
||||
rightMargin: 40 - auroraeTheme.paddingRight
|
||||
topMargin: 40 - auroraeTheme.paddingTop
|
||||
bottomMargin: 10 - auroraeTheme.paddingBottom
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
/********************************************************************
|
||||
Copyright (C) 2012 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
import QtQuick 2.0
|
||||
|
||||
Item {
|
||||
id: decorationPreview
|
||||
AuroraeDecoration {
|
||||
id: inactiveDecoration
|
||||
active: false
|
||||
anchors {
|
||||
fill: parent
|
||||
leftMargin: 40
|
||||
rightMargin: 10
|
||||
topMargin: 10
|
||||
bottomMargin: 40
|
||||
}
|
||||
}
|
||||
AuroraeDecoration {
|
||||
id: activeDecoration
|
||||
active: true
|
||||
anchors {
|
||||
fill: parent
|
||||
leftMargin: 10
|
||||
rightMargin: 40
|
||||
topMargin: 40
|
||||
bottomMargin: 10
|
||||
}
|
||||
}
|
||||
Component.onCompleted: {
|
||||
inactiveDecoration.source = mainScript;
|
||||
activeDecoration.source = mainScript;
|
||||
}
|
||||
}
|
|
@ -1,63 +1,85 @@
|
|||
/********************************************************************
|
||||
Copyright (C) 2012 Martin Gräßlin <mgraesslin@kde.org>
|
||||
Copyright (C) 2012 Nuno Pinheiro <nuno@oxygen-icons.org>
|
||||
/*
|
||||
* Copyright 2014 Martin Gräßlin <mgraesslin@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import QtQuick 2.1
|
||||
import QtQuick.Controls 1.2
|
||||
import org.kde.kwin.private.kdecoration 1.0 as KDecoration
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
import QtQuick 2.0
|
||||
import org.kde.kwin.kcmdecoration 0.1
|
||||
|
||||
ListView {
|
||||
id: listView
|
||||
x: 0
|
||||
y: 0
|
||||
model: decorationModel
|
||||
highlight: Rectangle {
|
||||
width: listView.width
|
||||
height: 150
|
||||
color: highlightColor
|
||||
opacity: 0.5
|
||||
}
|
||||
highlightMoveDuration: 250
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
delegate: Item {
|
||||
objectName: "decorationItem"
|
||||
width: listView.width
|
||||
height: 150
|
||||
PreviewItem {
|
||||
id: preview
|
||||
anchors.fill: parent
|
||||
visible: type == 0
|
||||
Component.onCompleted: {
|
||||
if (type == 0) {
|
||||
preview.library = model.library;
|
||||
ScrollView {
|
||||
ListView {
|
||||
id: listView
|
||||
objectName: "listView"
|
||||
model: decorationsModel
|
||||
highlight: Rectangle {
|
||||
width: listView.width
|
||||
height: 150
|
||||
color: highlightColor
|
||||
opacity: 0.5
|
||||
}
|
||||
highlightMoveDuration: 250
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
delegate: Item {
|
||||
width: listView.width
|
||||
height: 150
|
||||
KDecoration.Bridge {
|
||||
id: bridgeItem
|
||||
plugin: model["plugin"]
|
||||
theme: model["theme"]
|
||||
}
|
||||
KDecoration.Settings {
|
||||
id: settingsItem
|
||||
bridge: bridgeItem
|
||||
}
|
||||
KDecoration.Decoration {
|
||||
id: inactivePreview
|
||||
bridge: bridgeItem
|
||||
settings: settingsItem
|
||||
anchors.fill: parent
|
||||
Component.onCompleted: {
|
||||
client.caption = Qt.binding(function() { return model["display"]; });
|
||||
client.active = false;
|
||||
anchors.leftMargin = Qt.binding(function() { return 40 - (inactivePreview.decoration.shadow ? inactivePreview.decoration.shadow.paddingLeft : 0);});
|
||||
anchors.rightMargin = Qt.binding(function() { return 10 - (inactivePreview.decoration.shadow ? inactivePreview.decoration.shadow.paddingRight : 0);});
|
||||
anchors.topMargin = Qt.binding(function() { return 10 - (inactivePreview.decoration.shadow ? inactivePreview.decoration.shadow.paddingTop : 0);});
|
||||
anchors.bottomMargin = Qt.binding(function() { return 40 - (inactivePreview.decoration.shadow ? inactivePreview.decoration.shadow.paddingBottom : 0);});
|
||||
}
|
||||
}
|
||||
}
|
||||
Loader {
|
||||
source: type == 1 ? "AuroraePreview.qml" : ""
|
||||
anchors.fill: parent
|
||||
}
|
||||
Loader {
|
||||
source: type == 2 ? "DecorationPreview.qml" : ""
|
||||
anchors.fill: parent
|
||||
}
|
||||
MouseArea {
|
||||
hoverEnabled: false
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
listView.currentIndex = index;
|
||||
KDecoration.Decoration {
|
||||
id: activePreview
|
||||
bridge: bridgeItem
|
||||
settings: settingsItem
|
||||
anchors.fill: parent
|
||||
Component.onCompleted: {
|
||||
client.caption = Qt.binding(function() { return model["display"]; });
|
||||
client.active = true;
|
||||
anchors.leftMargin = Qt.binding(function() { return 10 - (activePreview.decoration.shadow ? activePreview.decoration.shadow.paddingLeft : 0);});
|
||||
anchors.rightMargin = Qt.binding(function() { return 40 - (activePreview.decoration.shadow ? activePreview.decoration.shadow.paddingRight : 0);});
|
||||
anchors.topMargin = Qt.binding(function() { return 40 - (activePreview.decoration.shadow ? activePreview.decoration.shadow.paddingTop : 0);});
|
||||
anchors.bottomMargin = Qt.binding(function() { return 10 - (activePreview.decoration.shadow ? activePreview.decoration.shadow.paddingBottom : 0);});
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
hoverEnabled: false
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
listView.currentIndex = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue