remove the shell from plasma-framework

This commit is contained in:
Marco Martin 2014-04-04 17:55:30 +02:00
parent dc17c39a95
commit e6f71eebd1
62 changed files with 0 additions and 11635 deletions

View File

@ -5,4 +5,3 @@ add_subdirectory(plasmapkg)
add_subdirectory(platformstatus)
add_subdirectory(scriptengines)
add_subdirectory(plasmaquick)
add_subdirectory(shell)

View File

@ -1,102 +0,0 @@
project(plasma-shell)
# Tell CMake to run moc when necessary:
set(CMAKE_AUTOMOC ON)
# As moc files are generated in the binary dir, tell CMake
# to always look for includes there:
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
find_package(Qt5Qml REQUIRED)
find_package(Qt5Quick REQUIRED)
find_package(Qt5DBus REQUIRED)
find_package(Qt5Script REQUIRED)
find_package(KF5CoreAddons REQUIRED)
find_package(KF5Crash REQUIRED)
find_package(KF5Solid REQUIRED)
find_package(KF5Activities REQUIRED)
find_package(KF5TextEditor) # not part of KF5.0
find_package(KF5DBusAddons ${KF5_VERSION} REQUIRED)
set(HAVE_KTEXTEDITOR ${KF5TextEditor_FOUND})
configure_file(config-ktexteditor.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-ktexteditor.h )
set(scripting_SRC
scripting/appinterface.cpp
scripting/applet.cpp
scripting/containment.cpp
scripting/configgroup.cpp
scripting/desktopscriptengine.cpp
scripting/i18n.cpp
scripting/panel.cpp
scripting/rect.cpp
scripting/scriptengine.cpp
scripting/widget.cpp
)
set(plasmashell_dbusXML dbus/org.kde.PlasmaShell.xml)
qt5_add_dbus_adaptor(scripting_SRC ${plasmashell_dbusXML} shellcorona.h ShellCorona plasmashelladaptor)
set (plasma_shell_SRCS
activity.cpp
main.cpp
containmentconfigview.cpp
currentcontainmentactionsmodel.cpp
desktopview.cpp
kidenticongenerator.cpp
panelview.cpp
panelconfigview.cpp
panelshadows.cpp
shellcorona.cpp
shellmanager.cpp
osd.cpp
${scripting_SRC}
)
if (KF5TextEditor_FOUND)
set (plasma_shell_SRCS ${plasma_shell_SRCS}
interactiveconsole.cpp
)
endif()
add_executable(plasma-shell
${plasma_shell_SRCS}
)
target_link_libraries(plasma-shell
Qt5::Quick
Qt5::Qml
Qt5::DBus
KF5::KIOCore
KF5::WindowSystem
KF5::CoreAddons
KF5::Crash
KF5::Plasma
KF5::PlasmaQuick
Qt5::Script
KF5::Solid
KF5::Declarative
KF5::I18n
KF5::XmlGui
KF5::IconThemes
KF5::Activities
KF5::GlobalAccel
KF5::DBusAddons
)
if (TARGET KF5::TextEditor)
target_link_libraries(plasma-shell KF5::TextEditor)
endif()
target_include_directories(plasma-shell PRIVATE "${CMAKE_BINARY_DIR}")
if(HAVE_X11)
target_link_libraries(plasma-shell ${X11_LIBRARIES} ${XCB_XCB_LIBRARY} )
target_link_libraries(plasma-shell Qt5::X11Extras)
endif()
install(TARGETS plasma-shell ${INSTALL_TARGETS_DEFAULT_ARGS})
install(FILES plasma-shell.desktop DESTINATION ${AUTOSTART_INSTALL_DIR})
install( FILES dbus/org.kde.PlasmaShell.xml DESTINATION ${DBUS_INTERFACES_INSTALL_DIR} )
add_subdirectory(widgetexplorer)

View File

@ -1,176 +0,0 @@
/*
* Copyright 2010 Chani Armitage <chani@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,
* 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 Library 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 "shellcorona.h"
#include "kidenticongenerator.h"
#include <QAction>
#include <QDebug>
#include <QPixmap>
#include <QString>
#include <QSize>
#include <QFile>
#include <kactioncollection.h>
#include <kconfig.h>
#include <kwindowsystem.h>
#include <Plasma/Containment>
#include <Plasma/Corona>
#include <kactivities/controller.h>
#include <kactivities/consumer.h>
#include "activity.h"
Activity::Activity(const QString &id, Plasma::Corona *parent)
: QObject(parent),
m_id(id),
m_plugin("org.kde.desktopcontainment"),//FIXME ask the corona
m_info(new KActivities::Info(id, this)),
m_activityConsumer(new KActivities::Consumer(this)),
m_current(false)
{
m_name = m_info->name();
m_icon = m_info->icon();
connect(m_info, SIGNAL(infoChanged()), this, SLOT(activityChanged()));
connect(m_info, SIGNAL(stateChanged(KActivities::Info::State)), this, SIGNAL(stateChanged()));
connect(m_info, SIGNAL(started()), this, SIGNAL(opened()));
connect(m_info, SIGNAL(stopped()), this, SIGNAL(closed()));
connect(m_info, SIGNAL(removed()), this, SIGNAL(removed()));
connect(m_info, SIGNAL(removed()), this, SLOT(cleanupActivity()));
connect(m_activityConsumer, SIGNAL(currentActivityChanged(QString)), this, SLOT(checkIfCurrent()));
checkIfCurrent();
}
Activity::~Activity()
{
}
void Activity::activityChanged()
{
setName(m_info->name());
setIcon(m_info->icon());
}
QString Activity::id()
{
return m_id;
}
QString Activity::name()
{
return m_name;
}
QPixmap Activity::pixmap(const QSize &size)
{
if (m_info->isValid() && !m_info->icon().isEmpty()) {
return QIcon::fromTheme(m_info->icon()).pixmap(size);
} else {
return KIdenticonGenerator::self()->generatePixmap(size.width(), m_id);
}
}
bool Activity::isCurrent()
{
return m_current;
//TODO maybe plasmaapp should cache the current activity to reduce dbus calls?
}
void Activity::checkIfCurrent()
{
const bool current = m_id == m_activityConsumer->currentActivity();
if (current != m_current) {
m_current = current;
emit currentStatusChanged();
}
}
KActivities::Info::State Activity::state()
{
return m_info->state();
}
void Activity::remove()
{
KActivities::Controller().removeActivity(m_id);
}
void Activity::cleanupActivity()
{
const QString name = "activities/" + m_id;
QFile::remove(QStandardPaths::writableLocation(QStandardPaths::DataLocation)+QChar('/')+name);
}
void Activity::activate()
{
KActivities::Controller().setCurrentActivity(m_id);
}
void Activity::setName(const QString &name)
{
m_name = name;
}
void Activity::setIcon(const QString &icon)
{
m_icon = icon;
}
void Activity::close()
{
KActivities::Controller().stopActivity(m_id);
}
KConfigGroup Activity::config() const
{
const QString name = "activities/" + m_id;
KConfig external(name, KConfig::SimpleConfig, QStandardPaths::GenericDataLocation);
//passing an empty string for the group name turns a kconfig into a kconfiggroup
return external.group(QString());
}
void Activity::open()
{
KActivities::Controller().startActivity(m_id);
}
void Activity::setDefaultPlugin(const QString &plugin)
{
m_plugin = plugin;
//FIXME save&restore this setting
}
QString Activity::defaultPlugin() const
{
return m_plugin;
}
const KActivities::Info * Activity::info() const
{
return m_info;
}
#include "activity.moc"
// vim: sw=4 sts=4 et tw=100

View File

@ -1,150 +0,0 @@
/*
* Copyright 2010 Chani Armitage <chani@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,
* 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 Library 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 ACTIVITY_H
#define ACTIVITY_H
#include <QObject>
#include <QHash>
#include <kactivities/info.h>
#include <kconfiggroup.h>
class QSize;
class QString;
class QPixmap;
class KConfig;
namespace KActivities
{
class Consumer;
} // namespace KActivities
namespace Plasma
{
class Containment;
class Corona;
} // namespace Plasma
class DesktopCorona;
/**
* This class represents one activity.
* an activity has an ID and a name, from nepomuk.
* it also is associated with one or more containments.
*
* do NOT construct these yourself; use DesktopCorona::activity()
*/
class Activity : public QObject
{
Q_OBJECT
public:
Activity(const QString &id, Plasma::Corona *parent = 0);
~Activity();
QString id();
QString name();
QPixmap pixmap(const QSize &size); //FIXME do we want diff. sizes? updates?
enum State {
Invalid = KActivities::Info::Invalid,
Running = KActivities::Info::Running,
Starting = KActivities::Info::Starting,
Stopped = KActivities::Info::Stopped,
Stopping = KActivities::Info::Stopping,
PreCreation = 32
};
/**
* whether this is the currently active activity
*/
bool isCurrent();
/**
* state of the activity
*/
KActivities::Info::State state();
/**
* set the plugin to use when creating new containments
*/
void setDefaultPlugin(const QString &plugin);
/**
* The plugin to use when creating new containments
*/
QString defaultPlugin() const;
/**
* @returns the info object for this activity
*/
const KActivities::Info * info() const;
KConfigGroup config() const;
Q_SIGNALS:
void infoChanged();
void stateChanged();
void currentStatusChanged();
void removed();
void opened();
void closed();
public Q_SLOTS:
void setName(const QString &name);
void setIcon(const QString &icon);
/**
* delete the activity forever
*/
void remove();
/**
* make this activity the current activity
*/
void activate();
/**
* save and remove all our containments
*/
void close();
/**
* load the saved containment(s) for this activity
*/
void open();
private Q_SLOTS:
void activityChanged();
void checkIfCurrent();
void cleanupActivity();
private:
QString m_id;
QString m_name;
QString m_icon;
QString m_plugin;
KActivities::Info *m_info;
KActivities::Consumer *m_activityConsumer;
bool m_current;
};
#endif

View File

@ -1,2 +0,0 @@
#cmakedefine01 HAVE_KTEXTEDITOR

View File

@ -1,185 +0,0 @@
/*
* Copyright 2013 Marco Martin <mart@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 "currentcontainmentactionsmodel.h"
#include "containmentconfigview.h"
#include "configmodel.h"
#include <kdeclarative/configpropertymap.h>
#include <QDebug>
#include <QDir>
#include <QQmlContext>
#include <QQmlEngine>
#include <QQmlComponent>
#include <klocalizedstring.h>
#include <Plasma/Corona>
#include <Plasma/ContainmentActions>
#include <Plasma/PluginLoader>
#include <qstandardpaths.h>
//////////////////////////////ContainmentConfigView
ContainmentConfigView::ContainmentConfigView(Plasma::Containment *cont, QWindow *parent)
: ConfigView(cont, parent),
m_containment(cont),
m_wallpaperConfigModel(0),
m_containmentActionConfigModel(0),
m_currentContainmentActionsModel(0),
m_currentWallpaperConfig(0),
m_ownWallpaperConfig(0)
{
qmlRegisterType<QAbstractItemModel>();
engine()->rootContext()->setContextProperty("configDialog", this);
setCurrentWallpaper(cont->containment()->wallpaper());
Plasma::Package pkg = Plasma::PluginLoader::self()->loadPackage("Plasma/Wallpaper");
pkg.setPath(m_containment->wallpaper());
QFile file(pkg.filePath("config", "main.xml"));
KConfigGroup cfg = m_containment->config();
cfg = KConfigGroup(&cfg, "Wallpaper");
syncWallpaperObjects();
}
ContainmentConfigView::~ContainmentConfigView()
{
}
void ContainmentConfigView::init()
{
setSource(QUrl::fromLocalFile(m_containment->corona()->package().filePath("containmentconfigurationui")));
}
PlasmaQuick::ConfigModel *ContainmentConfigView::containmentActionConfigModel()
{
if (!m_containmentActionConfigModel) {
m_containmentActionConfigModel = new PlasmaQuick::ConfigModel(this);
KPluginInfo::List actions = Plasma::PluginLoader::self()->listContainmentActionsInfo(QString());
Plasma::Package pkg = Plasma::PluginLoader::self()->loadPackage("Plasma/Generic");
foreach (const KPluginInfo &info, actions) {
pkg.setDefaultPackageRoot(QStandardPaths::locate(QStandardPaths::GenericDataLocation, "plasma/containmentactions", QStandardPaths::LocateDirectory));
m_containmentActionConfigModel->appendCategory(info.icon(), info.name(), pkg.filePath("ui", "config.qml"), info.pluginName());
}
}
return m_containmentActionConfigModel;
}
QAbstractItemModel *ContainmentConfigView::currentContainmentActionsModel()
{
if (!m_currentContainmentActionsModel) {
m_currentContainmentActionsModel = new CurrentContainmentActionsModel(m_containment, this);
}
return m_currentContainmentActionsModel;
}
PlasmaQuick::ConfigModel *ContainmentConfigView::wallpaperConfigModel()
{
if (!m_wallpaperConfigModel) {
m_wallpaperConfigModel = new PlasmaQuick::ConfigModel(this);
QStringList dirs(QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, "plasma/wallpapers", QStandardPaths::LocateDirectory));
Plasma::Package pkg = Plasma::PluginLoader::self()->loadPackage("Plasma/Generic");
foreach (const QString &dirPath, dirs) {
QDir dir(dirPath);
pkg.setDefaultPackageRoot(dirPath);
QStringList packages;
foreach (const QString &sdir, dir.entryList(QDir::AllDirs | QDir::Readable)) {
QString metadata = dirPath + '/' + sdir + "/metadata.desktop";
if (QFile::exists(metadata)) {
packages << sdir;
}
}
foreach (const QString &package, packages) {
pkg.setPath(package);
if (!pkg.isValid()) {
continue;
}
m_wallpaperConfigModel->appendCategory(pkg.metadata().icon(), pkg.metadata().name(), pkg.filePath("ui", "config.qml"), package);
}
}
}
return m_wallpaperConfigModel;
}
KDeclarative::ConfigPropertyMap *ContainmentConfigView::wallpaperConfiguration() const
{
return m_currentWallpaperConfig;
}
QString ContainmentConfigView::currentWallpaper() const
{
return m_currentWallpaper;
}
void ContainmentConfigView::setCurrentWallpaper(const QString &wallpaper)
{
if (m_currentWallpaper == wallpaper) {
return;
}
delete m_ownWallpaperConfig;
m_ownWallpaperConfig = 0;
if (m_containment->wallpaper() == wallpaper) {
syncWallpaperObjects();
} else {
//we have to construct an independent ConfigPropertyMap when we want to configure wallpapers that are not the current one
Plasma::Package pkg = Plasma::PluginLoader::self()->loadPackage("Plasma/Generic");
pkg.setDefaultPackageRoot("plasma/wallpapers");
pkg.setPath(wallpaper);
QFile file(pkg.filePath("config", "main.xml"));
KConfigGroup cfg = m_containment->config();
cfg = KConfigGroup(&cfg, "Wallpaper");
m_currentWallpaperConfig = m_ownWallpaperConfig = new KDeclarative::ConfigPropertyMap(new Plasma::ConfigLoader(&cfg, &file), this);
}
m_currentWallpaper = wallpaper;
emit currentWallpaperChanged();
emit wallpaperConfigurationChanged();
}
void ContainmentConfigView::applyWallpaper()
{
m_containment->setWallpaper(m_currentWallpaper);
delete m_ownWallpaperConfig;
m_ownWallpaperConfig = 0;
syncWallpaperObjects();
emit wallpaperConfigurationChanged();
}
void ContainmentConfigView::syncWallpaperObjects()
{
QObject *wallpaperGraphicsObject = m_containment->property("wallpaperGraphicsObject").value<QObject *>();
engine()->rootContext()->setContextProperty("wallpaper", wallpaperGraphicsObject);
//FIXME: why m_wallpaperGraphicsObject->property("configuration").value<ConfigPropertyMap *>() doesn't work?
m_currentWallpaperConfig = static_cast<KDeclarative::ConfigPropertyMap *>(wallpaperGraphicsObject->property("configuration").value<QObject *>());
}
#include "private/moc_containmentconfigview.cpp"

View File

@ -1,80 +0,0 @@
/*
* Copyright 2013 Marco Martin <mart@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 CONTAINMENTCONFIGVIEW_H
#define CONTAINMENTCONFIGVIEW_H
#include "configview.h"
namespace Plasma {
class Containment;
}
class QAbstractItemModel;
class CurrentContainmentActionsModel;
namespace KDeclarative {
class ConfigPropertyMap;
}
//TODO: out of the library?
class ContainmentConfigView : public PlasmaQuick::ConfigView
{
Q_OBJECT
Q_PROPERTY(PlasmaQuick::ConfigModel *containmentActionConfigModel READ containmentActionConfigModel CONSTANT)
Q_PROPERTY(QAbstractItemModel *currentContainmentActionsModel READ currentContainmentActionsModel CONSTANT)
Q_PROPERTY(PlasmaQuick::ConfigModel *wallpaperConfigModel READ wallpaperConfigModel CONSTANT)
Q_PROPERTY(KDeclarative::ConfigPropertyMap *wallpaperConfiguration READ wallpaperConfiguration NOTIFY wallpaperConfigurationChanged)
Q_PROPERTY(QString currentWallpaper READ currentWallpaper WRITE setCurrentWallpaper NOTIFY currentWallpaperChanged)
public:
ContainmentConfigView(Plasma::Containment *interface, QWindow *parent = 0);
virtual ~ContainmentConfigView();
virtual void init();
PlasmaQuick::ConfigModel *containmentActionConfigModel();
QAbstractItemModel *currentContainmentActionsModel();
PlasmaQuick::ConfigModel *wallpaperConfigModel();
QString currentWallpaper() const;
void setCurrentWallpaper(const QString &wallpaper);
KDeclarative::ConfigPropertyMap *wallpaperConfiguration() const;
Q_INVOKABLE void applyWallpaper();
Q_SIGNALS:
void currentWallpaperChanged();
void wallpaperConfigurationChanged();
protected:
void syncWallpaperObjects();
private:
Plasma::Containment *m_containment;
PlasmaQuick::ConfigModel *m_wallpaperConfigModel;
PlasmaQuick::ConfigModel *m_containmentActionConfigModel;
CurrentContainmentActionsModel *m_currentContainmentActionsModel;
QString m_currentWallpaper;
KDeclarative::ConfigPropertyMap *m_currentWallpaperConfig;
KDeclarative::ConfigPropertyMap *m_ownWallpaperConfig;
};
#endif // multiple inclusion guard

View File

@ -1,262 +0,0 @@
/*
* Copyright 2013 Marco Martin <mart@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 "currentcontainmentactionsmodel.h"
#include <QMouseEvent>
#include <QDebug>
#include <QDialog>
#include <QVBoxLayout>
#include <QDialogButtonBox>
#include <kaboutdata.h>
#include <kaboutapplicationdialog.h>
#include <klocalizedstring.h>
#include <Plasma/Corona>
#include <Plasma/Containment>
#include <Plasma/ContainmentActions>
#include <Plasma/PluginLoader>
CurrentContainmentActionsModel::CurrentContainmentActionsModel(Plasma::Containment *cotainment, QObject *parent)
: QStandardItemModel(parent),
m_containment(cotainment),
m_tempConfigParent(QString(), KConfig::SimpleConfig)
{
QHash<int, QByteArray> roleNames;
roleNames[ActionRole] = "action";
roleNames[PluginNameRole] = "pluginName";
roleNames[HasConfigurationInterfaceRole] = "hasConfigurationInterface";
setRoleNames(roleNames);
m_baseCfg = KConfigGroup(m_containment->corona()->config(), "ActionPlugins");
m_baseCfg = KConfigGroup(&m_baseCfg, QString::number(m_containment->containmentType()));
QHash<QString, Plasma::ContainmentActions*> actions = cotainment->containmentActions();
QHashIterator<QString, Plasma::ContainmentActions*> i(actions);
while (i.hasNext()) {
i.next();
QStandardItem *item = new QStandardItem();
item->setData(i.key(), ActionRole);
item->setData(i.value()->pluginInfo().pluginName(), PluginNameRole);
m_plugins[i.key()] = Plasma::PluginLoader::self()->loadContainmentActions(m_containment, i.value()->pluginInfo().pluginName());
m_plugins[i.key()]->setContainment(m_containment);
KConfigGroup cfg(&m_baseCfg, i.key());
m_plugins[i.key()]->restore(cfg);
item->setData(m_plugins[i.key()]->pluginInfo().property("X-Plasma-HasConfigurationInterface").toBool(), HasConfigurationInterfaceRole);
appendRow(item);
}
}
CurrentContainmentActionsModel::~CurrentContainmentActionsModel()
{
}
QString CurrentContainmentActionsModel::mouseEventString(int mouseButton, int modifiers)
{
QMouseEvent *mouse = new QMouseEvent(QEvent::MouseButtonRelease, QPoint(), (Qt::MouseButton)mouseButton, (Qt::MouseButton)mouseButton, (Qt::KeyboardModifiers) modifiers);
QString string = Plasma::ContainmentActions::eventToString(mouse);
delete mouse;
return string;
}
QString CurrentContainmentActionsModel::wheelEventString(const QPointF &delta, int mouseButtons, int modifiers)
{
QWheelEvent *wheel = new QWheelEvent(QPointF(), QPointF(), delta.toPoint(), QPoint(), 0, Qt::Vertical, (Qt::MouseButtons)mouseButtons, (Qt::KeyboardModifiers) modifiers);
QString string = Plasma::ContainmentActions::eventToString(wheel);
delete wheel;
return string;
}
bool CurrentContainmentActionsModel::isTriggerUsed(const QString &trigger)
{
return m_plugins.contains(trigger);
}
bool CurrentContainmentActionsModel::append(const QString &action, const QString &plugin)
{
if (m_plugins.contains(action)) {
return false;
}
QStandardItem *item = new QStandardItem();
item->setData(action, ActionRole);
item->setData(plugin, PluginNameRole);
m_plugins[action] = Plasma::PluginLoader::self()->loadContainmentActions(m_containment, plugin);
m_plugins[action]->setContainment(m_containment);
//empty config: the new one will ne in default state
KConfigGroup tempConfig(&m_tempConfigParent, "test");
m_plugins[action]->restore(tempConfig);
item->setData(m_plugins[action]->pluginInfo().property("X-Plasma-HasConfigurationInterface").toBool(), HasConfigurationInterfaceRole);
m_removedTriggers.removeAll(action);
appendRow(item);
return true;
}
void CurrentContainmentActionsModel::update(int row, const QString &action, const QString &plugin)
{
const QString oldPlugin = itemData(index(row, 0)).value(PluginNameRole).toString();
const QString oldTrigger = itemData(index(row, 0)).value(ActionRole).toString();
if (oldTrigger == action && oldPlugin == plugin) {
return;
}
QModelIndex idx = index(row, 0);
if (idx.isValid()) {
setData(idx, action, ActionRole);
setData(idx, plugin, PluginNameRole);
delete m_plugins[oldTrigger];
m_plugins.remove(oldTrigger);
if (oldPlugin != plugin) {
m_removedTriggers << oldTrigger;
}
if (!m_plugins.contains(action) || oldPlugin != plugin) {
delete m_plugins[action];
m_plugins[action] = Plasma::PluginLoader::self()->loadContainmentActions(m_containment, plugin);
m_plugins[action]->setContainment(m_containment);
//empty config: the new one will ne in default state
KConfigGroup tempConfig(&m_tempConfigParent, "test");
m_plugins[action]->restore(tempConfig);
setData(idx, m_plugins[action]->pluginInfo().property("X-Plasma-HasConfigurationInterface").toBool(), HasConfigurationInterfaceRole);
}
}
}
void CurrentContainmentActionsModel::remove(int row)
{
const QString action = itemData(index(row, 0)).value(ActionRole).toString();
removeRows(row, 1);
if (m_plugins.contains(action)) {
delete m_plugins[action];
m_plugins.remove(action);
m_removedTriggers << action;
}
}
void CurrentContainmentActionsModel::showConfiguration(int row)
{
const QString action = itemData(index(row, 0)).value(ActionRole).toString();
if (!m_plugins.contains(action)) {
return;
}
QDialog *configDlg = new QDialog();
configDlg->setAttribute(Qt::WA_DeleteOnClose);
QLayout *lay = new QVBoxLayout(configDlg);
configDlg->setLayout(lay);
configDlg->setWindowModality(Qt::WindowModal);
Plasma::ContainmentActions *pluginInstance = m_plugins[action];
//put the config in the dialog
QWidget *w = pluginInstance->createConfigurationInterface(configDlg);
QString title;
if (w) {
lay->addWidget(w);
title = w->windowTitle();
}
configDlg->setWindowTitle(title.isEmpty() ? i18n("Configure Plugin") :title);
//put buttons below
QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
Qt::Horizontal, configDlg);
lay->addWidget(buttons);
QObject::connect(buttons, &QDialogButtonBox::accepted,
[configDlg, pluginInstance] () {
pluginInstance->configurationAccepted();
configDlg->deleteLater();
});
QObject::connect(buttons, &QDialogButtonBox::rejected,
[configDlg] () {
configDlg->deleteLater();
});
configDlg->show();
}
void CurrentContainmentActionsModel::showAbout(int row)
{
const QString action = itemData(index(row, 0)).value(ActionRole).toString();
if (!m_plugins.contains(action)) {
return;
}
KPluginInfo info = m_plugins[action]->pluginInfo();
KAboutData aboutData(info.name().toUtf8(),
info.name().toUtf8(),
ki18n(info.name().toUtf8()).toString(),
info.version().toUtf8(), ki18n(info.comment().toUtf8()).toString(),
KAboutLicense::byKeyword(info.license()).key(), ki18n(QByteArray()).toString(), ki18n(QByteArray()).toString(), info.website().toLatin1(),
info.email().toLatin1());
aboutData.setProgramIconName(info.icon());
aboutData.addAuthor(ki18n(info.author().toUtf8()).toString(), ki18n(QByteArray()).toString(), info.email().toLatin1());
KAboutApplicationDialog *aboutDialog = new KAboutApplicationDialog(aboutData, qobject_cast<QWidget*>(parent()));
aboutDialog->show();
}
void CurrentContainmentActionsModel::save()
{
foreach (const QString &removedTrigger, m_removedTriggers) {
m_containment->setContainmentActions(removedTrigger, QString());
}
m_removedTriggers.clear();
QHashIterator<QString, Plasma::ContainmentActions*> i(m_plugins);
while (i.hasNext()) {
i.next();
KConfigGroup cfg(&m_baseCfg, i.key());
i.value()->save(cfg);
m_containment->setContainmentActions(i.key(), i.value()->pluginInfo().pluginName());
}
}
#include "private/moc_currentcontainmentactionsmodel.cpp"

View File

@ -1,68 +0,0 @@
/*
* Copyright 2013 Marco Martin <mart@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 CURRENTCONTAINMENTACTIONSMODEL_H
#define CURRENTCONTAINMENTACTIONSMODEL_H
#include <QStandardItemModel>
#include <kconfig.h>
#include <kconfiggroup.h>
namespace Plasma {
class Containment;
class ContainmentActions;
}
//This model load the data about available containment actions plugins, such as context menus that can be loaded on mouse click
//TODO: out of the library?
class CurrentContainmentActionsModel : public QStandardItemModel
{
Q_OBJECT
public:
enum Roles {
ActionRole = Qt::UserRole+1,
PluginNameRole,
HasConfigurationInterfaceRole
};
CurrentContainmentActionsModel(Plasma::Containment *cotainment, QObject *parent = 0);
~CurrentContainmentActionsModel();
Q_INVOKABLE bool isTriggerUsed(const QString &trigger);
Q_INVOKABLE QString mouseEventString(int mouseButtons, int modifiers);
Q_INVOKABLE QString wheelEventString(const QPointF &delta, int mouseButtons, int modifiers);
Q_INVOKABLE bool append(const QString &action, const QString &plugin);
Q_INVOKABLE void update(int row, const QString &action, const QString &plugin);
Q_INVOKABLE void remove(int row);
Q_INVOKABLE void showConfiguration(int row);
Q_INVOKABLE void showAbout(int row);
Q_INVOKABLE void save();
private:
Plasma::Containment *m_containment;
QHash<QString, Plasma::ContainmentActions *> m_plugins;
KConfigGroup m_baseCfg;
KConfigGroup m_tempConfig;
KConfig m_tempConfigParent;
QStringList m_removedTriggers;
};
#endif

View File

@ -1,15 +0,0 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.kde.PlasmaShell">
<method name="toggleDashboard">
</method>
<method name="setDashboardShown">
<arg name="show" type="b" direction="in"/>
</method>
<method name="showInteractiveConsole">
</method>
<method name="loadScriptInInteractiveConsole">
<arg name="script" type="s" direction="in"/>
</method>
</interface>
</node>

View File

@ -1,180 +0,0 @@
/*
* Copyright 2013 Marco Martin <mart@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 "desktopview.h"
#include "containmentconfigview.h"
#include "shellcorona.h"
#include "shellmanager.h"
#include <QQmlEngine>
#include <QQmlContext>
#include <QScreen>
#include <kwindowsystem.h>
#include <klocalizedstring.h>
#include <Plasma/Package>
DesktopView::DesktopView(ShellCorona *corona, QScreen *screen)
: PlasmaQuick::View(corona, 0),
m_stayBehind(false),
m_fillScreen(false),
m_dashboardShown(false)
{
setTitle(i18n("Desktop"));
setIcon(QIcon::fromTheme("user-desktop"));
setScreen(screen);
engine()->rootContext()->setContextProperty("desktop", this);
setSource(QUrl::fromLocalFile(corona->package().filePath("views", "Desktop.qml")));
connect(this, &QWindow::xChanged, [=]() {
if (m_fillScreen) {
setGeometry(this->screen()->geometry());
}
});
connect(this, &QWindow::yChanged, [=]() {
if (m_fillScreen) {
setGeometry(this->screen()->geometry());
}
});
}
DesktopView::~DesktopView()
{
}
bool DesktopView::stayBehind() const
{
return m_stayBehind;
}
void DesktopView::setStayBehind(bool stayBehind)
{
if (ShellManager::s_forceWindowed || stayBehind == m_stayBehind) {
return;
}
if (stayBehind) {
KWindowSystem::setType(winId(), NET::Desktop);
} else {
KWindowSystem::setType(winId(), NET::Normal);
}
m_stayBehind = stayBehind;
emit stayBehindChanged();
}
bool DesktopView::fillScreen() const
{
return m_fillScreen;
}
void DesktopView::setFillScreen(bool fillScreen)
{
if (ShellManager::s_forceWindowed || fillScreen == m_fillScreen) {
return;
}
m_fillScreen = fillScreen;
if (m_fillScreen) {
setGeometry(screen()->geometry());
setMinimumSize(screen()->geometry().size());
setMaximumSize(screen()->geometry().size());
connect(screen(), &QScreen::geometryChanged, this, static_cast<void (QWindow::*)(const QRect&)>(&QWindow::setGeometry));
} else {
disconnect(screen(), &QScreen::geometryChanged, this, static_cast<void (QWindow::*)(const QRect&)>(&QWindow::setGeometry));
}
emit fillScreenChanged();
}
void DesktopView::setDashboardShown(bool shown)
{
if (shown) {
if (m_stayBehind) {
KWindowSystem::setType(winId(), NET::Normal);
KWindowSystem::clearState(winId(), NET::SkipTaskbar|NET::KeepBelow);
}
setFlags(Qt::FramelessWindowHint | Qt::CustomizeWindowHint);
raise();
KWindowSystem::raiseWindow(winId());
KWindowSystem::forceActiveWindow(winId());
QObject *wpGraphicObject = containment()->property("wallpaperGraphicsObject").value<QObject *>();
if (wpGraphicObject) {
wpGraphicObject->setProperty("opacity", 0.3);
}
} else {
if (m_stayBehind) {
KWindowSystem::setType(winId(), NET::Desktop);
KWindowSystem::setState(winId(), NET::SkipTaskbar|NET::SkipPager|NET::KeepBelow);
}
lower();
KWindowSystem::lowerWindow(winId());
QObject *wpGraphicObject = containment()->property("wallpaperGraphicsObject").value<QObject *>();
if (wpGraphicObject) {
wpGraphicObject->setProperty("opacity", 1);
}
}
m_dashboardShown = shown;
}
bool DesktopView::event(QEvent *e)
{
if (e->type() == QEvent::Close) {
//prevent ALT+F4 from killing the shell
e->ignore();
return true;
}
return PlasmaQuick::View::event(e);
}
bool DesktopView::isDashboardShown() const
{
return m_dashboardShown;
}
void DesktopView::showConfigurationInterface(Plasma::Applet *applet)
{
if (m_configView) {
m_configView.data()->hide();
m_configView.data()->deleteLater();
}
if (!applet || !applet->containment()) {
return;
}
Plasma::Containment *cont = qobject_cast<Plasma::Containment *>(applet);
if (cont) {
m_configView = new ContainmentConfigView(cont);
} else {
m_configView = new PlasmaQuick::ConfigView(applet);
}
m_configView.data()->init();
m_configView.data()->show();
}
#include "moc_desktopview.cpp"

View File

@ -1,68 +0,0 @@
/*
* Copyright 2013 Marco Martin <mart@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 DESKTOVIEW_H
#define DESKTOVIEW_H
#include <view.h>
#include "panelconfigview.h"
#include <QtCore/qpointer.h>
class ShellCorona;
class DesktopView : public PlasmaQuick::View
{
Q_OBJECT
Q_PROPERTY(bool stayBehind READ stayBehind WRITE setStayBehind NOTIFY stayBehindChanged)
Q_PROPERTY(bool fillScreen READ fillScreen WRITE setFillScreen NOTIFY fillScreenChanged)
public:
explicit DesktopView(ShellCorona *corona, QScreen *screen);
virtual ~DesktopView();
bool stayBehind() const;
void setStayBehind(bool stayBehind);
bool fillScreen() const;
void setFillScreen(bool fillScreen);
void setDashboardShown(bool shown);
bool isDashboardShown() const;
protected:
bool event(QEvent *e);
protected Q_SLOTS:
/**
* It will be called when the configuration is requested
*/
virtual void showConfigurationInterface(Plasma::Applet *applet);
Q_SIGNALS:
void stayBehindChanged();
void fillScreenChanged();
private:
QPointer<PlasmaQuick::ConfigView> m_configView;
bool m_stayBehind : 1;
bool m_fillScreen : 1;
bool m_dashboardShown : 1;
};
#endif // DESKTOVIEW_H

View File

@ -1,576 +0,0 @@
/*
* Copyright 2009 Aaron Seigo <aseigo@kde.org>
* Copyright 2014 Marco Martin <mart@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 "interactiveconsole.h"
#include <QDateTime>
#include <QDBusConnection>
#include <QDBusMessage>
#include <QFile>
#include <QHBoxLayout>
#include <QLabel>
#include <QSplitter>
#include <QToolButton>
#include <QVBoxLayout>
#include <QStandardPaths>
#include <QIcon>
#include <QFileDialog>
#include <QAction>
#include <KShell>
#include <KMessageBox>
#include <klocalizedstring.h>
#include <QMenu>
#include <KServiceTypeTrader>
#include <KStandardAction>
#include <QTextBrowser>
#include <KTextEdit>
#include <KTextEditor/ConfigInterface>
#include <KTextEditor/Document>
#include <KTextEditor/View>
#include <KToolBar>
#include <Plasma/Package>
#include "scripting/desktopscriptengine.h"
#include "shellpluginloader.h"
#include "shellcorona.h"
//TODO:
// interative help?
static const QString s_autosaveFileName("interactiveconsoleautosave.js");
static const QString s_kwinService = "org.kde.kwin.Scripting";
InteractiveConsole::InteractiveConsole(ShellCorona *corona, QWidget *parent)
: QDialog(parent),
m_corona(corona),
m_splitter(new QSplitter(Qt::Vertical, this)),
m_editorPart(0),
m_editor(0),
m_output(0),
m_loadAction(KStandardAction::open(this, SLOT(openScriptFile()), this)),
m_saveAction(KStandardAction::saveAs(this, SLOT(saveScript()), this)),
m_clearAction(KStandardAction::clear(this, SLOT(clearEditor()), this)),
m_executeAction(new QAction(QIcon::fromTheme("system-run"), i18n("&Execute"), this)),
m_plasmaAction(new QAction(QIcon::fromTheme("plasma"), i18nc("Toolbar Button to switch to Plasma Scripting Mode", "Plasma"), this)),
m_kwinAction(new QAction(QIcon::fromTheme("kwin"), i18nc("Toolbar Button to switch to KWin Scripting Mode", "KWin"), this)),
m_snippetsMenu(new QMenu(i18n("Templates"), this)),
m_fileDialog(0),
m_closeWhenCompleted(false),
m_mode(PlasmaConsole)
{
addAction(KStandardAction::close(this, SLOT(close()), this));
addAction(m_saveAction);
addAction(m_clearAction);
setWindowTitle(i18n("Desktop Shell Scripting Console"));
setAttribute(Qt::WA_DeleteOnClose);
//setButtons(QDialog::None);
QWidget *widget = new QWidget(m_splitter);
QVBoxLayout *editorLayout = new QVBoxLayout(widget);
QLabel *label = new QLabel(i18n("Editor"), widget);
QFont f = label->font();
f.setBold(true);
label->setFont(f);
editorLayout->addWidget(label);
connect(m_snippetsMenu, SIGNAL(aboutToShow()), this, SLOT(populateTemplatesMenu()));
QToolButton *loadTemplateButton = new QToolButton(this);
loadTemplateButton->setPopupMode(QToolButton::InstantPopup);
loadTemplateButton->setMenu(m_snippetsMenu);
loadTemplateButton->setText(i18n("Load"));
connect(loadTemplateButton, SIGNAL(triggered(QAction*)), this, SLOT(loadTemplate(QAction*)));
QToolButton *useTemplateButton = new QToolButton(this);
useTemplateButton->setPopupMode(QToolButton::InstantPopup);
useTemplateButton->setMenu(m_snippetsMenu);
useTemplateButton->setText(i18n("Use"));
connect(useTemplateButton, SIGNAL(triggered(QAction*)), this, SLOT(useTemplate(QAction*)));
QActionGroup *modeGroup = new QActionGroup(this);
modeGroup->addAction(m_plasmaAction);
modeGroup->addAction(m_kwinAction);
m_plasmaAction->setCheckable(true);
m_kwinAction->setCheckable(true);
m_plasmaAction->setChecked(true);
connect(modeGroup, SIGNAL(triggered(QAction*)), this, SLOT(modeChanged()));
KToolBar *toolBar = new KToolBar(this, true, false);
toolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
toolBar->addAction(m_loadAction);
toolBar->addAction(m_saveAction);
toolBar->addAction(m_clearAction);
toolBar->addAction(m_executeAction);
toolBar->addAction(m_plasmaAction);
toolBar->addAction(m_kwinAction);
toolBar->addWidget(loadTemplateButton);
toolBar->addWidget(useTemplateButton);
editorLayout->addWidget(toolBar);
KService::List offers = KServiceTypeTrader::self()->query("KTextEditor/Document");
foreach (const KService::Ptr service, offers) {
m_editorPart = service->createInstance<KTextEditor::Document>(widget);
if (m_editorPart) {
m_editorPart->setHighlightingMode("JavaScript/PlasmaDesktop");
KTextEditor::View * view = m_editorPart->createView(widget);
view->setContextMenu(view->defaultContextMenu());
KTextEditor::ConfigInterface *config = qobject_cast<KTextEditor::ConfigInterface*>(view);
if (config) {
config->setConfigValue("line-numbers", true);
config->setConfigValue("dynamic-word-wrap", true);
}
editorLayout->addWidget(view);
connect(m_editorPart, SIGNAL(textChanged(KTextEditor::Document*)),
this, SLOT(scriptTextChanged()));
break;
}
}
if (!m_editorPart) {
m_editor = new KTextEdit(widget);
editorLayout->addWidget(m_editor);
connect(m_editor, SIGNAL(textChanged()), this, SLOT(scriptTextChanged()));
}
m_splitter->addWidget(widget);
widget = new QWidget(m_splitter);
QVBoxLayout *outputLayout = new QVBoxLayout(widget);
label = new QLabel(i18n("Output"), widget);
f = label->font();
f.setBold(true);
label->setFont(f);
outputLayout->addWidget(label);
KToolBar *outputToolBar = new KToolBar(widget, true, false);
outputToolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
QAction *clearOutputAction = KStandardAction::clear(this, SLOT(clearOutput()), this);
outputToolBar->addAction(clearOutputAction);
outputLayout->addWidget(outputToolBar);
m_output = new QTextBrowser(widget);
outputLayout->addWidget(m_output);
m_splitter->addWidget(widget);
QVBoxLayout *l = new QVBoxLayout(this);
l->addWidget(m_splitter);
KConfigGroup cg(KSharedConfig::openConfig(), "InteractiveConsole");
restoreGeometry(cg.readEntry<QByteArray>("Geometry", QByteArray()));
m_splitter->setStretchFactor(0, 10);
m_splitter->restoreState(cg.readEntry("SplitterState", QByteArray()));
scriptTextChanged();
connect(m_executeAction, SIGNAL(triggered()), this, SLOT(evaluateScript()));
m_executeAction->setShortcut(Qt::CTRL + Qt::Key_E);
const QString autosave = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/" + s_autosaveFileName;
if (QFile::exists(autosave)) {
loadScript(autosave);
}
}
InteractiveConsole::~InteractiveConsole()
{
KConfigGroup cg(KSharedConfig::openConfig(), "InteractiveConsole");
cg.writeEntry("Geometry", saveGeometry());
cg.writeEntry("SplitterState", m_splitter->saveState());
}
void InteractiveConsole::setMode(ConsoleMode mode)
{
m_mode = mode;
switch (mode) {
case PlasmaConsole:
m_plasmaAction->setChecked(true);
break;
case KWinConsole:
m_kwinAction->setChecked(true);
break;
}
}
void InteractiveConsole::modeChanged()
{
if (m_plasmaAction->isChecked()) {
m_mode = PlasmaConsole;
} else if (m_kwinAction->isChecked()) {
m_mode = KWinConsole;
}
}
void InteractiveConsole::loadScript(const QString &script)
{
if (m_editorPart) {
m_editorPart->closeUrl(false);
if (m_editorPart->openUrl(QUrl::fromLocalFile(script))) {
m_editorPart->setHighlightingMode("JavaScript/PlasmaDesktop");
return;
}
} else {
QFile file(KShell::tildeExpand(script));
if (file.open(QIODevice::ReadOnly | QIODevice::Text) ) {
m_editor->setText(file.readAll());
return;
}
}
m_output->append(i18n("Unable to load script file <b>%1</b>", script));
}
void InteractiveConsole::showEvent(QShowEvent *)
{
if (m_editorPart) {
m_editorPart->views().first()->setFocus();
} else {
m_editor->setFocus();
}
}
void InteractiveConsole::closeEvent(QCloseEvent *event)
{
onClose();
QDialog::closeEvent(event);
}
void InteractiveConsole::reject()
{
onClose();
QDialog::reject();
}
void InteractiveConsole::onClose()
{
// need to save first!
const QString path = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/" + s_autosaveFileName;
m_closeWhenCompleted = true;
saveScript(QUrl::fromLocalFile(path));
}
void InteractiveConsole::print(const QString &string)
{
m_output->append(string);
}
void InteractiveConsole::scriptTextChanged()
{
const bool enable = m_editorPart ? !m_editorPart->isEmpty() : !m_editor->document()->isEmpty();
m_saveAction->setEnabled(enable);
m_clearAction->setEnabled(enable);
m_executeAction->setEnabled(enable);
}
void InteractiveConsole::openScriptFile()
{
delete m_fileDialog;
m_fileDialog = new QFileDialog();
m_fileDialog->setAcceptMode(QFileDialog::AcceptOpen);
m_fileDialog->setWindowTitle(i18n("Open Script File"));
QStringList mimetypes;
mimetypes << "application/javascript";
m_fileDialog->setMimeTypeFilters(mimetypes);
connect(m_fileDialog, SIGNAL(finished(int)), this, SLOT(openScriptUrlSelected(int)));
m_fileDialog->show();
}
void InteractiveConsole::openScriptUrlSelected(int result)
{
if (!m_fileDialog) {
return;
}
if (result == QDialog::Accepted) {
const QUrl url = m_fileDialog->selectedUrls().first();
if (!url.isEmpty()) {
loadScriptFromUrl(url);
}
}
m_fileDialog->deleteLater();
m_fileDialog = 0;
}
void InteractiveConsole::loadScriptFromUrl(const QUrl &url)
{
if (m_editorPart) {
m_editorPart->closeUrl(false);
m_editorPart->openUrl(url);
m_editorPart->setHighlightingMode("JavaScript/PlasmaDesktop");
} else {
m_editor->clear();
m_editor->setEnabled(false);
if (m_job) {
m_job.data()->kill();
}
m_job = KIO::get(url, KIO::Reload, KIO::HideProgressInfo);
connect(m_job.data(), SIGNAL(data(KIO::Job*,QByteArray)), this, SLOT(scriptFileDataRecvd(KIO::Job*,QByteArray)));
connect(m_job.data(), SIGNAL(result(KJob*)), this, SLOT(reenableEditor(KJob*)));
}
}
void InteractiveConsole::populateTemplatesMenu()
{
m_snippetsMenu->clear();
QMap<QString, KService::Ptr> sorted;
const QString constraint = QString("[X-Plasma-Shell] == '%1'")
.arg(qApp->applicationName());
KService::List templates = KServiceTypeTrader::self()->query("Plasma/LayoutTemplate", constraint);
foreach (const KService::Ptr &service, templates) {
sorted.insert(service->name(), service);
}
QMapIterator<QString, KService::Ptr> it(sorted);
Plasma::Package package = ShellPluginLoader::self()->loadPackage("Plasma/LayoutTemplate");
while (it.hasNext()) {
it.next();
KPluginInfo info(it.value());
const QString path = QStandardPaths::locate(QStandardPaths::GenericDataLocation
, package.defaultPackageRoot() + '/' + info.pluginName() + '/');
if (!path.isEmpty()) {
package.setPath(info.pluginName());
const QString scriptFile = package.filePath("mainscript");
if (!scriptFile.isEmpty()) {
QAction *action = m_snippetsMenu->addAction(info.name());
action->setData(info.pluginName());
}
}
}
}
void InteractiveConsole::loadTemplate(QAction *action)
{
Plasma::Package package = ShellPluginLoader::self()->loadPackage("Plasma/LayoutTemplate");
const QString pluginName = action->data().toString();
const QString path = QStandardPaths::locate(QStandardPaths::GenericDataLocation
, package.defaultPackageRoot() + '/' + pluginName + '/');
if (!path.isEmpty()) {
package.setPath(pluginName);
const QString scriptFile = package.filePath("mainscript");
if (!scriptFile.isEmpty()) {
loadScriptFromUrl(QUrl::fromLocalFile(scriptFile));
}
}
}
void InteractiveConsole::useTemplate(QAction *action)
{
QString code("var template = loadTemplate('" + action->data().toString() + "')");
if (m_editorPart) {
const QList<KTextEditor::View *> views = m_editorPart->views();
if (views.isEmpty()) {
m_editorPart->insertLines(m_editorPart->lines(), QStringList() << code);
} else {
KTextEditor::Cursor cursor = views.at(0)->cursorPosition();
m_editorPart->insertLines(cursor.line(), QStringList() << code);
cursor.setLine(cursor.line() + 1);
views.at(0)->setCursorPosition(cursor);
}
} else {
m_editor->insertPlainText(code);
}
}
void InteractiveConsole::scriptFileDataRecvd(KIO::Job *job, const QByteArray &data)
{
Q_ASSERT(m_editor);
if (job == m_job.data()) {
m_editor->insertPlainText(data);
}
}
void InteractiveConsole::saveScript()
{
if (m_editorPart) {
m_editorPart->documentSaveAs();
return;
}
delete m_fileDialog;
m_fileDialog = new QFileDialog();
m_fileDialog->setAcceptMode(QFileDialog::AcceptSave);
m_fileDialog->setWindowTitle(i18n("Save Script File"));
QStringList mimetypes;
mimetypes << "application/javascript";
m_fileDialog->setMimeTypeFilters(mimetypes);
connect(m_fileDialog, SIGNAL(finished(int)), this, SLOT(saveScriptUrlSelected(int)));
m_fileDialog->show();
}
void InteractiveConsole::saveScriptUrlSelected(int result)
{
if (!m_fileDialog) {
return;
}
if (result == QDialog::Accepted) {
const QUrl url = m_fileDialog->selectedUrls().first();
if (!url.isEmpty()) {
saveScript(url);
}
}
m_fileDialog->deleteLater();
m_fileDialog = 0;
}
void InteractiveConsole::saveScript(const QUrl &url)
{
if (m_editorPart) {
m_editorPart->saveAs(url);
} else {
m_editor->setEnabled(false);
if (m_job) {
m_job.data()->kill();
}
m_job = KIO::put(url, -1, KIO::HideProgressInfo);
connect(m_job.data(), SIGNAL(dataReq(KIO::Job*,QByteArray&)), this, SLOT(scriptFileDataReq(KIO::Job*,QByteArray&)));
connect(m_job.data(), SIGNAL(result(KJob*)), this, SLOT(reenableEditor(KJob*)));
}
}
void InteractiveConsole::scriptFileDataReq(KIO::Job *job, QByteArray &data)
{
Q_ASSERT(m_editor);
if (!m_job || m_job.data() != job) {
return;
}
data.append(m_editor->toPlainText().toLocal8Bit());
m_job.clear();
}
void InteractiveConsole::reenableEditor(KJob* job)
{
Q_ASSERT(m_editor);
if (m_closeWhenCompleted && job->error() != 0) {
close();
}
m_closeWhenCompleted = false;
m_editor->setEnabled(true);
}
void InteractiveConsole::evaluateScript()
{
//qDebug() << "evaluating" << m_editor->toPlainText();
const QString path = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/" + s_autosaveFileName;
saveScript(QUrl::fromLocalFile(path));
m_output->moveCursor(QTextCursor::End);
QTextCursor cursor = m_output->textCursor();
m_output->setTextCursor(cursor);
QTextCharFormat format;
format.setFontWeight(QFont::Bold);
format.setFontUnderline(true);
if (cursor.position() > 0) {
cursor.insertText("\n\n");
}
QDateTime dt = QDateTime::currentDateTime();
cursor.insertText(i18n("Executing script at %1", QLocale().toString(dt)));
format.setFontWeight(QFont::Normal);
format.setFontUnderline(false);
QTextBlockFormat block = cursor.blockFormat();
block.setLeftMargin(10);
cursor.insertBlock(block, format);
QTime t;
t.start();
if (m_mode == PlasmaConsole) {
WorkspaceScripting::DesktopScriptEngine scriptEngine(m_corona, false, this);
connect(&scriptEngine, SIGNAL(print(QString)), this, SLOT(print(QString)));
connect(&scriptEngine, SIGNAL(printError(QString)), this, SLOT(print(QString)));
connect(&scriptEngine, SIGNAL(createPendingPanelViews()), m_corona, SLOT(createWaitingPanels()));
scriptEngine.evaluateScript(m_editorPart ? m_editorPart->text() : m_editor->toPlainText());
} else if (m_mode == KWinConsole) {
QDBusMessage message = QDBusMessage::createMethodCall(s_kwinService, "/Scripting", QString(), "loadScript");
QList<QVariant> arguments;
arguments << QVariant(path);
message.setArguments(arguments);
QDBusMessage reply = QDBusConnection::sessionBus().call(message);
if (reply.type() == QDBusMessage::ErrorMessage) {
print(reply.errorMessage());
} else {
const int id = reply.arguments().first().toInt();
QDBusConnection::sessionBus().connect(s_kwinService, "/" + QString::number(id), QString(), "print", this, SLOT(print(QString)));
QDBusConnection::sessionBus().connect(s_kwinService, "/" + QString::number(id), QString(), "printError", this, SLOT(print(QString)));
message = QDBusMessage::createMethodCall(s_kwinService, "/" + QString::number(id), QString(), "run");
reply = QDBusConnection::sessionBus().call(message);
if (reply.type() == QDBusMessage::ErrorMessage) {
print(reply.errorMessage());
}
}
}
cursor.insertText("\n\n");
format.setFontWeight(QFont::Bold);
// xgettext:no-c-format
cursor.insertText(i18n("Runtime: %1ms", QString::number(t.elapsed())), format);
block.setLeftMargin(0);
cursor.insertBlock(block);
m_output->ensureCursorVisible();
}
void InteractiveConsole::clearEditor()
{
if (m_editorPart) {
m_editorPart->clear();
} else {
m_editor->clear();
}
}
void InteractiveConsole::clearOutput()
{
m_output->clear();
}
#include "interactiveconsole.moc"

View File

@ -1,118 +0,0 @@
/*
* Copyright 2009 Aaron Seigo <aseigo@kde.org>
* Copyright 2014 Marco Martin <mart@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 INTERACTIVECONSOLE
#define INTERACTIVECONSOLE
#include <QWeakPointer>
#include <QScriptValue>
#include <QDialog>
#include <KIO/Job>
class QSplitter;
class QAction;
class QFileDialog;
class QMenu;
class KTextEdit;
class QTextBrowser;
class ShellCorona;
namespace KTextEditor
{
class Document;
} // namespace KParts
namespace Plasma
{
class Corona;
} // namespace Plasma
class ScriptEngine;
class InteractiveConsole : public QDialog
{
Q_OBJECT
public:
InteractiveConsole(ShellCorona *corona, QWidget *parent = 0);
~InteractiveConsole();
void loadScript(const QString &path);
enum ConsoleMode {
PlasmaConsole,
KWinConsole
};
void setMode(ConsoleMode mode);
protected:
void showEvent(QShowEvent *);
void closeEvent(QCloseEvent *event);
protected Q_SLOTS:
void print(const QString &string);
void reject();
private Q_SLOTS:
void openScriptFile();
void saveScript();
void scriptTextChanged();
void evaluateScript();
void clearEditor();
void clearOutput();
void scriptFileDataRecvd(KIO::Job *job, const QByteArray &data);
void scriptFileDataReq(KIO::Job *job, QByteArray &data);
void reenableEditor(KJob *job);
void saveScriptUrlSelected(int result);
void openScriptUrlSelected(int result);
void loadScriptFromUrl(const QUrl &url);
void populateTemplatesMenu();
void loadTemplate(QAction *);
void useTemplate(QAction *);
void modeChanged();
private:
void onClose();
void saveScript(const QUrl &url);
ShellCorona *m_corona;
QSplitter *m_splitter;
KTextEditor::Document *m_editorPart;
KTextEdit *m_editor;
QTextBrowser *m_output;
QAction *m_loadAction;
QAction *m_saveAction;
QAction *m_clearAction;
QAction *m_executeAction;
QAction *m_plasmaAction;
QAction *m_kwinAction;
QMenu *m_snippetsMenu;
QFileDialog *m_fileDialog;
QWeakPointer<KIO::Job> m_job;
bool m_closeWhenCompleted;
ConsoleMode m_mode;
};
#endif

View File

@ -1,302 +0,0 @@
/*
* Copyright 2010 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library/Lesser General Public License
* version 2, or (at your option) any later version, as published by the
* Free Software Foundation
*
* 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 Library/Lesser 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 "kidenticongenerator.h"
#include <QHash>
#include <QPainter>
#include <QDebug>
#include <QCryptographicHash>
#include <kiconeffect.h>
#include <Plasma/Svg>
#include <Plasma/Theme>
#define VALUE_LIMIT_UP 192
#define VALUE_LIMIT_DOWN 64
class KIdenticonGenerator::Private {
public:
QPixmap generatePattern(int size, quint32 hash, QIcon::Mode mode);
QString elementName(const QString & element, QIcon::Mode mode);
QColor colorForHash(quint32 hash) const;
quint32 hash(const QString & data);
static KIdenticonGenerator * instance;
Plasma::Theme *theme;
Plasma::Svg shapes;
Plasma::Svg svg;
};
QPixmap KIdenticonGenerator::Private::generatePattern(int size, quint32 hash, QIcon::Mode mode)
{
// We are dividing the pixmap into 9 blocks - 3 x 3
int blockSize = size / 3;
// pulling parts of the hash
quint32 tmp = hash;
quint8 block[4];
block[0] = tmp & 31; tmp >>= 5;
block[1] = tmp & 31; tmp >>= 5;
block[2] = tmp & 31; tmp >>= 5;
// Painting alpha channel
QPixmap pixmapAlpha(size, size);
pixmapAlpha.fill(Qt::black);
QPainter painterAlpha(& pixmapAlpha);
QRectF rect(0, 0, blockSize + 0.5, blockSize + 0.5);
for (int i = 0; i < 4; i++) {
// Painting the corner item
rect.moveTopLeft(QPoint(0, 0));
shapes.paint(& painterAlpha, rect, "shape" + QString::number(block[0] + 1));
// Painting side item
rect.moveTopLeft(QPoint(blockSize, 0));
shapes.paint(& painterAlpha, rect, "shape" + QString::number(block[1] + 1));
// Rotating the canvas to paint other edges
painterAlpha.translate(size, 0);
painterAlpha.rotate(90);
}
// Painting center item
rect.moveTopLeft(QPoint(blockSize, blockSize));
shapes.paint(& painterAlpha, rect, "shape" + QString::number(block[2] + 1));
painterAlpha.end();
// Painting final pixmap
QPixmap pixmapResult(size, size);
pixmapResult.fill(Qt::transparent);
// QRadialGradient gradient(50, 50, 100);
// gradient.setColorAt(0, color.lighter());
// gradient.setColorAt(1, color.darker());
QPainter resultPainter(& pixmapResult);
// resultPainter.fillRect(0, 0, size, size, gradient);
svg.paint(& resultPainter, QRect(0, 0, size, size), elementName("content", mode));
resultPainter.end();
pixmapResult.setAlphaChannel(pixmapAlpha);
// QImage itmp = pixmapResult.toImage();
// KIconEffect::colorize(itmp, colorForHash(hash), 1.0);
// pixmapResult = pixmapResult.fromImage(itmp);
return pixmapResult;
}
QColor KIdenticonGenerator::Private::colorForHash(quint32 hash) const
{
// Color is chosen according to hash
QColor color;
// Getting the value from color svg, but we must restrain it to
// values in range from VALUE_LIMIT_DOWN to VALUE_LIMIT_UP
int value = theme->color(Plasma::Theme::TextColor).value();
if (value < VALUE_LIMIT_DOWN) {
value = VALUE_LIMIT_DOWN;
} else if (value > VALUE_LIMIT_UP) {
value = VALUE_LIMIT_UP;
}
color.setHsv(
hash % 359 + 1, // hue depending on hash
250, // high saturation level
value
);
return color;
}
QString KIdenticonGenerator::Private::elementName(const QString & element, QIcon::Mode mode)
{
QString prefix;
switch (mode) {
case QIcon::Normal:
prefix = "normal-";
break;
case QIcon::Disabled:
prefix = "disabled-";
break;
case QIcon::Selected:
prefix = "selected-";
break;
case QIcon::Active:
prefix = "active-";
break;
default:
break;
}
if (svg.hasElement(prefix + element)) {
return prefix + element;
} else {
return element;
}
}
quint32 KIdenticonGenerator::Private::hash(const QString & data)
{
// qHash function doesn't give random enough results
// and gives similar hashes for similar strings.
QByteArray bytes = QCryptographicHash::hash(data.toUtf8(), QCryptographicHash::Md5);
// Generating hash
quint32 hash = 0;
char * hashBytes = (char *) & hash;
for (int i = 0; i < bytes.size(); i++) {
// Using XOR for mixing the bytes because
// it is fast and cryptographically safe
// (more than enough for our use-case)
hashBytes[i % 4] ^= bytes.at(i);
}
return hash;
}
KIdenticonGenerator * KIdenticonGenerator::Private::instance = NULL;
KIdenticonGenerator * KIdenticonGenerator::self()
{
if (!Private::instance) {
Private::instance = new KIdenticonGenerator();
}
return Private::instance;
}
KIdenticonGenerator::KIdenticonGenerator()
: d(new Private())
{
d->theme = new Plasma::Theme(0);
// loading SVGs
d->shapes.setImagePath("widgets/identiconshapes");
d->shapes.setContainsMultipleImages(true);
d->svg.setImagePath("widgets/identiconsvg");
d->svg.setContainsMultipleImages(true);
}
KIdenticonGenerator::~KIdenticonGenerator()
{
delete d->theme;
}
#define generateIconModes( PARAM ) \
for (int omode = QIcon::Normal; omode <= QIcon::Selected; omode++) { \
QIcon::Mode mode = (QIcon::Mode)omode; \
result.addPixmap(generatePixmap(size, PARAM, mode), mode); \
}
QIcon KIdenticonGenerator::generate(int size, quint32 hash)
{
QIcon result;
generateIconModes(hash);
return result;
}
QIcon KIdenticonGenerator::generate(int size, const QString & data)
{
QIcon result;
generateIconModes(data);
return result;
}
QIcon KIdenticonGenerator::generate(int size, const QIcon & icon)
{
QIcon result;
generateIconModes(icon);
return result;
}
QPixmap KIdenticonGenerator::generatePixmap(int size, QString id, QIcon::Mode mode)
{
return generatePixmap(size, d->hash(id), mode);
}
QPixmap KIdenticonGenerator::generatePixmap(int size, quint32 hash, QIcon::Mode mode)
{
QPixmap pixmap(size, size);
pixmap.fill(Qt::transparent);
// Painting background and the pattern
{
QPainter painter(& pixmap);
d->svg.paint(& painter, QRect(0, 0, size, size), d->elementName("background", mode));
painter.drawPixmap(0, 0, d->generatePattern(size, hash, mode));
painter.end();
}
// coloring the painted image
QImage itmp = pixmap.toImage();
KIconEffect::colorize(itmp, d->colorForHash(hash), 1.0);
if (mode == QIcon::Disabled) {
KIconEffect::toGray(itmp, 0.7);
}
pixmap = pixmap.fromImage(itmp);
// Drawing the overlay
{
QPainter painter(& pixmap);
d->svg.paint(& painter, QRect(0, 0, size, size), d->elementName("overlay", mode));
}
return pixmap;
}
QPixmap KIdenticonGenerator::generatePixmap(int size, const QIcon & icon, QIcon::Mode mode)
{
QPixmap pixmap(size, size);
pixmap.fill(Qt::transparent);
QRect paintRect(0, 0, size, size);
// Painting background and the pattern
QPainter painter(& pixmap);
d->svg.paint(& painter, QRect(0, 0, size, size), d->elementName("background", mode));
icon.paint(& painter, paintRect, Qt::AlignCenter, mode);
painter.end();
return pixmap;
}

View File

@ -1,48 +0,0 @@
/*
* Copyright 2010 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library/Lesser General Public License
* version 2, or (at your option) any later version, as published by the
* Free Software Foundation
*
* 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 Library/Lesser 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 KIDENTICONGENERATOR_H
#define KIDENTICONGENERATOR_H
#include <QPixmap>
#include <QIcon>
#include <Plasma/Svg>
class KIdenticonGenerator {
public:
static KIdenticonGenerator * self();
~KIdenticonGenerator();
QPixmap generatePixmap(int size, QString id, QIcon::Mode mode = QIcon::Normal);
QPixmap generatePixmap(int size, quint32 hash, QIcon::Mode mode = QIcon::Normal);
QPixmap generatePixmap(int size, const QIcon & icon, QIcon::Mode mode = QIcon::Normal);
QIcon generate(int size, const QString & data);
QIcon generate(int size, quint32 hash);
QIcon generate(int size, const QIcon & icon);
private:
KIdenticonGenerator();
class Private;
Private * const d;
};
#endif // KIDENTICONGENERATOR_H

View File

@ -1,92 +0,0 @@
/*
* Copyright 2012 Marco Martin <mart@kde.org>
* Copyright 2013 Sebastian Kügler <sebas@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 <QApplication>
#include <qcommandlineparser.h>
#include <QtQml/QQmlDebuggingEnabler>
#include <QDebug>
#include <kdbusservice.h>
#include <klocalizedstring.h>
#include "shellpluginloader.h"
#include "shellmanager.h"
static const char description[] = "Plasma Shell";
static const char version[] = "2.0";
static QCommandLineParser parser;
void noMessageOutput(QtMsgType type, const char *msg)
{
Q_UNUSED(type);
Q_UNUSED(msg);
}
int main(int argc, char** argv)
{
QQmlDebuggingEnabler debugEnabler;
QApplication app(argc, argv);
app.setApplicationName("plasma_shell");
app.setOrganizationDomain("kde.org");
app.setApplicationVersion(version);
app.setQuitOnLastWindowClosed(false);
parser.setApplicationDescription(description);
KDBusService service(KDBusService::Unique);
QCommandLineOption dbg(QStringList() << QStringLiteral("d") <<
QStringLiteral("qmljsdebugger"),
QStringLiteral("Enable QML Javascript debugger"));
QCommandLineOption win(QStringList() << QStringLiteral("w") <<
QStringLiteral("windowed"),
QStringLiteral("Force a windowed view for testing purposes"));
QCommandLineOption respawn(QStringList() << QStringLiteral("n") <<
QStringLiteral("no-respawn"),
QStringLiteral("Do not restart plasma-shell automatically after a crash"));
QCommandLineOption crash(QStringList() << QStringLiteral("c") << QStringLiteral("crashes"),
QStringLiteral("Recent number of crashes"),
QStringLiteral("n"));
QCommandLineOption shutup(QStringList() << QStringLiteral("s") << QStringLiteral("shut-up"),
QStringLiteral("Shuts up the output"));
parser.addVersionOption();
parser.addHelpOption();
parser.addOption(dbg);
parser.addOption(win);
parser.addOption(respawn);
parser.addOption(crash);
parser.addOption(shutup);
parser.process(app);
if (parser.isSet(shutup)) {
qInstallMsgHandler(noMessageOutput);
}
Plasma::PluginLoader::setPluginLoader(new ShellPluginLoader);
ShellManager::setCrashCount(parser.value(crash).toInt());
ShellManager::s_forceWindowed = parser.isSet(win);
ShellManager::s_noRespawn = parser.isSet(respawn);
ShellManager::instance();
return app.exec();
}

View File

@ -1,324 +0,0 @@
/*
* Copyright (c) 2009 Chani Armitage <chani@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 "mousepluginwidget.h"
#include <Plasma/Containment>
#include <kaboutdata.h>
#include <kaboutapplicationdialog.h>
#include <KDebug>
#include <QApplication>
#include <QComboBox>
#include <QDialog>
#include <QDialogButtonBox>
#include <QGridLayout>
Q_DECLARE_METATYPE(KPluginInfo)
MousePluginWidget::MousePluginWidget(const QString &pluginName, const QString &trigger, QGridLayout *layoutHack, QWidget *parent)
: QObject(parent),
m_configDlg(0),
m_containment(0),
m_lastConfigLocation(trigger),
m_tempConfigParent(QString(), KConfig::SimpleConfig)
{
KPluginInfo::List plugins = Plasma::ContainmentActions::listContainmentActionsInfo();
if (plugins.isEmpty()) {
//panic!!
QLabel *fail = new QLabel(i18n("No plugins found, check your installation."), parent);
layoutHack->addWidget(fail, 0, 0);
return;
}
//make us some widgets
m_pluginList = new QComboBox(parent);
m_aboutButton = new QToolButton(parent);
m_clearButton = new QToolButton(parent);
m_triggerButton = new MouseInputButton(parent);
m_configButton = new QToolButton(parent);
//m_ui.description->setText(plugin.comment());
//plugin list
//FIXME is there some way to share this across all the entries?
foreach (const KPluginInfo& plugin, plugins) {
if (plugin.property("NoDisplay").toBool()) {
continue;
}
m_pluginList->addItem(KIcon(plugin.icon()), plugin.name(), QVariant::fromValue(plugin));
if (plugin.pluginName() == pluginName) {
m_pluginList->setCurrentIndex(m_pluginList->count() - 1);
m_plugin = plugin;
}
}
if (! m_plugin.isValid()) {
//probably an empty string; pick the first one
m_pluginList->setCurrentIndex(0);
m_plugin = plugins.first();
}
//I can haz config?
m_tempConfig = KConfigGroup(&m_tempConfigParent, "test");
if (!m_plugin.property("X-Plasma-HasConfigurationInterface").toBool()) {
m_configButton->setVisible(false);
}
setTrigger(trigger);
//pretty icons for the buttons
m_aboutButton->setIcon(KIcon("dialog-information"));
m_aboutButton->setToolTip(i18nc("About mouse action", "About"));
m_triggerButton->setIcon(KIcon("input-mouse"));
m_configButton->setIcon(KIcon("configure"));
m_configButton->setToolTip(i18nc("Configure mouse action", "Configure"));
m_clearButton->setIcon(KIcon("list-remove"));
m_clearButton->setToolTip(i18nc("Remove mouse action", "Remove"));
//HACK
//FIXME what's the Right Way to do this?
int row = layoutHack->rowCount();
layoutHack->addWidget(m_triggerButton, row, 0);
layoutHack->addWidget(m_pluginList, row, 1);
layoutHack->addWidget(m_configButton, row, 2);
layoutHack->addWidget(m_aboutButton, row, 3);
layoutHack->addWidget(m_clearButton, row, 4);
//connect
connect(m_pluginList, SIGNAL(currentIndexChanged(int)), this, SLOT(setPlugin(int)));
connect(m_triggerButton, SIGNAL(triggerChanged(QString,QString)), this, SLOT(changeTrigger(QString,QString)));
connect(m_configButton, SIGNAL(clicked()), this, SLOT(configure()));
connect(m_clearButton, SIGNAL(clicked()), this, SLOT(clearTrigger()));
connect(m_aboutButton, SIGNAL(clicked()), this, SLOT(showAbout()));
}
MousePluginWidget::~MousePluginWidget()
{
delete m_pluginInstance.data();
}
void MousePluginWidget::setPlugin(int index)
{
m_plugin = m_pluginList->itemData(index).value<KPluginInfo>();
//clear all the old plugin's stuff
if (m_configDlg) {
kDebug() << "can't happen";
m_configDlg->deleteLater();
m_configDlg = 0;
}
if (m_pluginInstance) {
delete m_pluginInstance.data();
kDebug() << "tried to delete instance";
}
//reset config button
bool hasConfig = m_plugin.property("X-Plasma-HasConfigurationInterface").toBool();
m_configButton->setVisible(hasConfig);
m_tempConfig.deleteGroup();
m_lastConfigLocation.clear();
//FIXME a stray mousewheel deleting your config would be no fun.
//perhaps we could mark it for deletion, and then... um.. not delete it if the user goes back to
//that plugin? but then we'd have to record which plugin the config is *for*...
emit configChanged(m_triggerButton->trigger());
}
void MousePluginWidget::setContainment(Plasma::Containment *ctmt)
{
//note: since the old plugin's parent is the old containment,
//we let that containment take care of deleting it
m_containment = ctmt;
}
void MousePluginWidget::setTrigger(const QString &trigger)
{
m_triggerButton->setTrigger(trigger);
updateConfig(trigger);
}
void MousePluginWidget::clearTrigger()
{
QString oldTrigger = m_triggerButton->trigger();
setTrigger(QString());
emit triggerChanged(oldTrigger, QString());
//byebye!
m_pluginList->deleteLater();
m_aboutButton->deleteLater();
m_clearButton->deleteLater();
m_triggerButton->deleteLater();
m_configButton->deleteLater();
deleteLater();
}
void MousePluginWidget::changeTrigger(const QString &oldTrigger, const QString& newTrigger)
{
updateConfig(newTrigger);
emit triggerChanged(oldTrigger, newTrigger);
}
void MousePluginWidget::updateConfig(const QString &trigger)
{
m_configButton->setEnabled(!trigger.isEmpty());
m_pluginList->setEnabled(!trigger.isEmpty());
}
void MousePluginWidget::configure()
{
if (!m_pluginInstance) {
Plasma::ContainmentActions *pluginInstance = Plasma::ContainmentActions::load(m_containment, m_plugin.pluginName());
if (!pluginInstance) {
//FIXME tell user
kDebug() << "failed to load plugin!";
return;
}
m_pluginInstance = pluginInstance;
if (m_lastConfigLocation.isEmpty()) {
pluginInstance->restore(m_tempConfig);
} else {
KConfigGroup cfg = m_containment->containmentActionsConfig();
cfg = KConfigGroup(&cfg, m_lastConfigLocation);
pluginInstance->restore(cfg);
}
}
if (!m_configDlg) {
m_configDlg = new QDialog(qobject_cast<QWidget*>(parent()));
QLayout *lay = new QVBoxLayout(m_configDlg);
m_configDlg->setLayout(lay);
m_configDlg->setWindowModality(Qt::WindowModal);
//put the config in the dialog
QWidget *w = m_pluginInstance.data()->createConfigurationInterface(m_configDlg);
if (w) {
lay->addWidget(w);
}
const QString title = w->windowTitle();
m_configDlg->setWindowTitle(title.isEmpty() ? i18n("Configure Plugin") :title);
//put buttons below
QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
Qt::Horizontal, m_configDlg);
lay->addWidget(buttons);
//TODO other signals?
connect(buttons, SIGNAL(accepted()), this, SLOT(acceptConfig()));
connect(buttons, SIGNAL(rejected()), this, SLOT(rejectConfig()));
}
m_configDlg->show();
}
void MousePluginWidget::acceptConfig()
{
kDebug() << "accept";
if (m_pluginInstance) {
m_pluginInstance.data()->configurationAccepted();
}
m_configDlg->deleteLater();
m_configDlg = 0;
emit configChanged(m_triggerButton->trigger());
}
void MousePluginWidget::rejectConfig()
{
kDebug() << "reject";
m_configDlg->deleteLater();
m_configDlg = 0;
}
void MousePluginWidget::prepareForSave()
{
if (!m_configButton->isVisible() || m_pluginInstance || m_lastConfigLocation.isEmpty()) {
return;
}
//back up our config because it'll be erased for saving
KConfigGroup cfg = m_containment->containmentActionsConfig();
cfg = KConfigGroup(&cfg, m_lastConfigLocation);
cfg.copyTo(&m_tempConfig);
//kDebug() << "copied to temp";
}
void MousePluginWidget::save()
{
const QString trigger = m_triggerButton->trigger();
if (trigger.isEmpty()) {
m_lastConfigLocation.clear();
return;
}
if (m_pluginInstance || !m_lastConfigLocation.isEmpty()) {
KConfigGroup cfg = m_containment->containmentActionsConfig();
cfg = KConfigGroup(&cfg, trigger);
if (m_pluginInstance) {
m_pluginInstance.data()->save(cfg);
} else {
m_tempConfig.copyTo(&cfg);
}
m_lastConfigLocation = trigger;
}
m_containment->setContainmentActions(trigger, m_plugin.pluginName());
}
//copied from appletbrowser.cpp
//FIXME add a feature to KAboutApplicationDialog to delete the object
/* This is just a wrapper around KAboutApplicationDialog that deletes
the KAboutData object that it is associated with, when it is deleted.
This is required to free memory correctly when KAboutApplicationDialog
is called with a temporary KAboutData that is allocated on the heap.
(see the code below, in AppletBrowserWidget::infoAboutApplet())
*/
class KAboutApplicationDialog2 : public KAboutApplicationDialog
{
public:
KAboutApplicationDialog2(KAboutData *ab, QWidget *parent = 0)
: KAboutApplicationDialog(ab, parent), m_ab(ab) {}
~KAboutApplicationDialog2()
{
delete m_ab;
}
private:
KAboutData *m_ab;
};
void MousePluginWidget::showAbout()
{
KAboutData *aboutData = new KAboutData(m_plugin.name().toUtf8(),
m_plugin.name().toUtf8(),
ki18n(m_plugin.name().toUtf8()),
m_plugin.version().toUtf8(), ki18n(m_plugin.comment().toUtf8()),
m_plugin.fullLicense().key(), ki18n(QByteArray()), ki18n(QByteArray()), m_plugin.website().toLatin1(),
m_plugin.email().toLatin1());
aboutData->setProgramIconName(m_plugin.icon());
aboutData->addAuthor(ki18n(m_plugin.author().toUtf8()), ki18n(QByteArray()), m_plugin.email().toLatin1());
KAboutApplicationDialog *aboutDialog = new KAboutApplicationDialog2(aboutData, qobject_cast<QWidget*>(parent()));
aboutDialog->show();
}
// vim: sw=4 sts=4 et tw=100

View File

@ -1,75 +0,0 @@
/*
* Copyright (c) 2009 Chani Armitage <chani@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 MOUSEPLUGINWIDGET_H
#define MOUSEPLUGINWIDGET_H
#include <QDialog>
#include <QLabel>
#include <QToolButton>
#include <kconfiggroup.h>
#include <plasma/containmentactions.h>
#include "mouseinputbutton.h"
class QComboBox;
class QGridLayout;
class MousePluginWidget : public QObject
{
Q_OBJECT
public:
MousePluginWidget(const QString &plugin, const QString &trigger, QGridLayout *layoutHack, QWidget *parent = 0);
~MousePluginWidget();
void setTrigger(const QString &trigger);
void prepareForSave();
void save();
signals:
void triggerChanged(const QString &oldTrigger, const QString &newTrigger);
void configChanged(const QString &trigger);
private slots:
void changeTrigger(const QString &oldTrigger, const QString& newTrigger);
void configure();
void acceptConfig();
void rejectConfig();
void showAbout();
private:
void updateConfig(const QString &trigger);
QComboBox *m_pluginList;
QDialog *m_configDlg;
KPluginInfo m_plugin;
QWeakPointer<Plasma::ContainmentActions> m_pluginInstance;
Plasma::Containment *m_containment;
QString m_lastConfigLocation;
KConfigGroup m_tempConfig;
KConfig m_tempConfigParent;
};
#endif

View File

@ -1,133 +0,0 @@
/*
* Copyright 2014 (c) Martin Klapetek <mklapetek@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 "osd.h"
#include "shellpluginloader.h"
#include "shellcorona.h"
#include <QDBusConnection>
#include <QTimer>
#include <QWindow>
#include <QDebug>
#include <QUrl>
#include <Plasma/Package>
#include <KDeclarative/QmlObject>
#include <klocalizedstring.h>
Osd::Osd(ShellCorona *corona)
: QObject(corona)
{
const QString osdPath = corona->lookAndFeelPackage().filePath("osdmainscript");
if (osdPath.isEmpty()) {
qWarning() << "Failed to load the OSD script file from" << osdPath;
return;
}
m_osdObject = new KDeclarative::QmlObject(this);
m_osdObject->setSource(QUrl::fromLocalFile(osdPath));
m_timeout = m_osdObject->rootObject()->property("timeout").toInt();
QDBusConnection::sessionBus().registerObject("/org/kde/osdService", this, QDBusConnection::ExportAllSlots);
m_osdTimer = new QTimer(this);
m_osdTimer->setSingleShot(true);
connect(m_osdTimer, SIGNAL(timeout()),
this, SLOT(hideOsd()));
}
Osd::~Osd()
{
}
void Osd::brightnessChanged(int percent)
{
// FIXME: need brightness icon
showProgress(QString(), percent);
}
void Osd::volumeChanged(int percent)
{
QString icon;
if (percent >= 75) {
icon = QStringLiteral("audio-volume-high");
} else if (percent < 75 && percent >= 25) {
icon = QStringLiteral("audio-volume-medium");
} else if (percent < 25 && percent > 0) {
icon = QStringLiteral("audio-volume-low");
} else if (percent == 0) {
icon = QStringLiteral("audio-volume-muted");
showText(icon, i18n("Audio Muted"));
return;
}
showProgress(icon, percent);
}
void Osd::mediaPlayerVolumeChanged(int percent, const QString &playerName, const QString &playerIconName)
{
if (percent == 0) {
showText(playerIconName, i18nc("OSD informing that some media app is muted, eg. Amarok Muted", "%1 Muted", playerName));
} else {
showProgress(playerIconName, percent, playerName);
}
}
void Osd::kbdLayoutChanged(const QString &layoutName)
{
//FIXME: need a kbd icon
showText(QString(), layoutName);
}
void Osd::virtualDesktopChanged(const QString &currentVirtualDesktopName)
{
//FIXME: need a VD icon
showText(QString(), currentVirtualDesktopName);
}
void Osd::showProgress(const QString &icon, const int percent, const QString &additionalText)
{
int value = qBound(0, percent, 100);
m_osdObject->rootObject()->setProperty("osdValue", value);
m_osdObject->rootObject()->setProperty("osdAdditionalText", additionalText);
m_osdObject->rootObject()->setProperty("showingProgress", true);
m_osdObject->rootObject()->setProperty("icon", icon);
showOsd();
}
void Osd::showText(const QString &icon, const QString &text)
{
m_osdObject->rootObject()->setProperty("osdValue", text);
m_osdObject->rootObject()->setProperty("showingProgress", false);
m_osdObject->rootObject()->setProperty("icon", icon);
showOsd();
}
void Osd::showOsd()
{
m_osdObject->rootObject()->setProperty("visible", true);
m_osdTimer->start(m_timeout);
}
void Osd::hideOsd()
{
m_osdObject->rootObject()->setProperty("visible", false);
}

View File

@ -1,62 +0,0 @@
/*
* Copyright 2014 (c) Martin Klapetek <mklapetek@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 OSD_H
#define OSD_H
#include <QObject>
#include <QString>
namespace KDeclarative {
class QmlObject;
}
namespace Plasma {
class Package;
}
class QTimer;
class ShellCorona;
class Osd : public QObject {
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.kde.osdService")
public:
Osd(ShellCorona *corona);
~Osd();
public Q_SLOTS:
void brightnessChanged(int percent);
void volumeChanged(int percent);
void mediaPlayerVolumeChanged(int percent, const QString &playerName, const QString &playerIconName);
void kbdLayoutChanged(const QString &layoutName);
void virtualDesktopChanged(const QString &currentVirtualDesktopName);
private Q_SLOTS:
void hideOsd();
private:
void showProgress(const QString &icon, const int percent, const QString &additionalText = QString());
void showText(const QString &icon, const QString &text);
void showOsd();
KDeclarative::QmlObject *m_osdObject;
QTimer *m_osdTimer;
int m_timeout;
};
#endif // OSD_H

View File

@ -1,145 +0,0 @@
/*
* Copyright 2013 Marco Martin <mart@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 "panelconfigview.h"
#include "panelview.h"
#include "panelshadows_p.h"
#include <QDebug>
#include <QDir>
#include <QQmlComponent>
#include <QQmlEngine>
#include <QQmlContext>
#include <QScreen>
#include <QAction>
#include <klocalizedstring.h>
#include <kwindoweffects.h>
#include <KActionCollection>
#include <Plasma/Containment>
#include <Plasma/Corona>
#include <Plasma/PluginLoader>
//////////////////////////////PanelConfigView
PanelConfigView::PanelConfigView(Plasma::Containment *containment, PanelView *panelView, QWindow *parent)
: ConfigView(containment, parent),
m_containment(containment),
m_panelView(panelView)
{
m_visibilityMode = panelView->visibilityMode();
panelView->setVisibilityMode(PanelView::WindowsGoBelow);
setScreen(panelView->screen());
connect(panelView, &QWindow::screenChanged, [=](QScreen *screen){setScreen(screen); syncGeometry();});
setFlags(Qt::BypassWindowManagerHint);
KWindowEffects::enableBlurBehind(winId(), true);
updateContrast();
connect(&m_theme, &Plasma::Theme::themeChanged, this, &PanelConfigView::updateContrast);
engine()->rootContext()->setContextProperty("panel", panelView);
engine()->rootContext()->setContextProperty("configDialog", this);
connect(containment, &Plasma::Containment::formFactorChanged,
this, &PanelConfigView::syncGeometry);
PanelShadows::self()->addWindow(this);
}
PanelConfigView::~PanelConfigView()
{
m_panelView->setVisibilityMode(m_visibilityMode);
PanelShadows::self()->removeWindow(this);
}
void PanelConfigView::init()
{
setSource(QUrl::fromLocalFile(m_containment->corona()->package().filePath("panelconfigurationui")));
syncGeometry();
}
void PanelConfigView::updateContrast()
{
KWindowEffects::enableBackgroundContrast(winId(), m_theme.backgroundContrastEnabled(),
m_theme.backgroundContrast(),
m_theme.backgroundIntensity(),
m_theme.backgroundSaturation());
}
void PanelConfigView::showAddWidgetDialog()
{
QAction *addWidgetAction = m_containment->actions()->action("add widgets");
if (addWidgetAction) {
addWidgetAction->trigger();
}
}
void PanelConfigView::addPanelSpacer()
{
m_containment->createApplet("org.kde.plasma.panelspacer");
}
void PanelConfigView::syncGeometry()
{
if (!m_containment || !rootObject()) {
return;
}
if (m_containment->formFactor() == Plasma::Types::Vertical) {
resize(rootObject()->implicitWidth(), screen()->size().height());
if (m_containment->location() == Plasma::Types::LeftEdge) {
setPosition(m_panelView->geometry().right(), screen()->geometry().top());
} else if (m_containment->location() == Plasma::Types::RightEdge) {
setPosition(m_panelView->geometry().left() - width(), screen()->geometry().top());
}
} else {
resize(screen()->size().width(), rootObject()->implicitHeight());
if (m_containment->location() == Plasma::Types::TopEdge) {
setPosition(screen()->geometry().left(), m_panelView->geometry().bottom());
} else if (m_containment->location() == Plasma::Types::BottomEdge) {
setPosition(screen()->geometry().left(), m_panelView->geometry().top() - height());
}
}
}
void PanelConfigView::focusOutEvent(QFocusEvent *ev)
{
Q_UNUSED(ev)
close();
}
void PanelConfigView::setVisibilityMode(PanelView::VisibilityMode mode)
{
if (m_visibilityMode == mode) {
return;
}
m_visibilityMode = mode;
emit visibilityModeChanged();
}
PanelView::VisibilityMode PanelConfigView::visibilityMode() const
{
return m_visibilityMode;
}
#include "moc_panelconfigview.cpp"

View File

@ -1,78 +0,0 @@
/*
* Copyright 2013 Marco Martin <mart@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 PANELCONFIGVIEW_H
#define PANELCONFIGVIEW_H
#include "configview.h"
#include "panelview.h"
#include <QQuickItem>
#include <QQuickView>
#include <QJSValue>
#include <QQmlListProperty>
#include <QStandardItemModel>
#include <Plasma/Theme>
class AppletInterface;
class ConfigPropertyMap;
class PanelView;
namespace Plasma {
class Containment;
}
class PanelConfigView : public PlasmaQuick::ConfigView
{
Q_OBJECT
Q_PROPERTY(PanelView::VisibilityMode visibilityMode READ visibilityMode WRITE setVisibilityMode NOTIFY visibilityModeChanged)
public:
PanelConfigView(Plasma::Containment *interface, PanelView *panelView, QWindow *parent = 0);
virtual ~PanelConfigView();
void init();
PanelView::VisibilityMode visibilityMode() const;
void setVisibilityMode(PanelView::VisibilityMode mode);
public Q_SLOTS:
void showAddWidgetDialog();
void addPanelSpacer();
protected:
void focusOutEvent(QFocusEvent *ev);
protected Q_SLOTS:
void syncGeometry();
private Q_SLOTS:
void updateContrast();
Q_SIGNALS:
void visibilityModeChanged();
private:
Plasma::Containment *m_containment;
PanelView *m_panelView;
PanelView::VisibilityMode m_visibilityMode;
Plasma::Theme m_theme;
};
#endif // multiple inclusion guard

View File

@ -1,506 +0,0 @@
/*
* Copyright 2011 by Aaron Seigo <aseigo@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2,
* 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 Library 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 "panelshadows_p.h"
#include <QWindow>
#include <QPainter>
#include <config-plasma.h>
#if HAVE_X11
#include <QX11Info>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/Xlib-xcb.h>
#include <fixx11h.h>
#endif
#include <qdebug.h>
class PanelShadows::Private
{
public:
Private(PanelShadows *shadows)
: q(shadows)
#if HAVE_X11
,_connection( 0x0 ),
_gc( 0x0 )
, m_isX11(QX11Info::isPlatformX11())
#endif
{
}
~Private()
{
// Do not call clearPixmaps() from here: it creates new QPixmap(),
// which causes a crash when application is stopping.
freeX11Pixmaps();
}
void freeX11Pixmaps();
void clearPixmaps();
void setupPixmaps();
Qt::HANDLE createPixmap(const QPixmap& source);
void initPixmap(const QString &element);
QPixmap initEmptyPixmap(const QSize &size);
void updateShadow(const QWindow *window, Plasma::FrameSvg::EnabledBorders);
void clearShadow(const QWindow *window);
void updateShadows();
void windowDestroyed(QObject *deletedObject);
void setupData(Plasma::FrameSvg::EnabledBorders enabledBorders);
PanelShadows *q;
QList<QPixmap> m_shadowPixmaps;
QPixmap m_emptyCornerPix;
QPixmap m_emptyCornerLeftPix;
QPixmap m_emptyCornerTopPix;
QPixmap m_emptyCornerRightPix;
QPixmap m_emptyCornerBottomPix;
QPixmap m_emptyVerticalPix;
QPixmap m_emptyHorizontalPix;
#if HAVE_X11
//! xcb connection
xcb_connection_t* _connection;
//! graphical context
xcb_gcontext_t _gc;
bool m_isX11;
#endif
QHash<Plasma::FrameSvg::EnabledBorders, QVector<unsigned long> > data;
QHash<const QWindow *, Plasma::FrameSvg::EnabledBorders> m_windows;
};
class DialogShadowsSingleton
{
public:
DialogShadowsSingleton()
{
}
PanelShadows self;
};
Q_GLOBAL_STATIC(DialogShadowsSingleton, privateDialogShadowsSelf)
PanelShadows::PanelShadows(QObject *parent, const QString &prefix)
: Plasma::Svg(parent),
d(new Private(this))
{
setImagePath(prefix);
connect(this, SIGNAL(repaintNeeded()), this, SLOT(updateShadows()));
}
PanelShadows::~PanelShadows()
{
delete d;
}
PanelShadows *PanelShadows::self()
{
return &privateDialogShadowsSelf->self;
}
void PanelShadows::addWindow(const QWindow *window, Plasma::FrameSvg::EnabledBorders enabledBorders)
{
if (!window) {
return;
}
d->m_windows[window] = enabledBorders;
d->updateShadow(window, enabledBorders);
connect(window, SIGNAL(destroyed(QObject*)),
this, SLOT(windowDestroyed(QObject*)), Qt::UniqueConnection);
}
void PanelShadows::removeWindow(const QWindow *window)
{
if (!d->m_windows.contains(window)) {
return;
}
d->m_windows.remove(window);
disconnect(window, 0, this, 0);
d->clearShadow(window);
if (d->m_windows.isEmpty()) {
d->clearPixmaps();
}
}
void PanelShadows::Private::windowDestroyed(QObject *deletedObject)
{
m_windows.remove(static_cast<QWindow *>(deletedObject));
if (m_windows.isEmpty()) {
clearPixmaps();
}
}
void PanelShadows::Private::updateShadows()
{
setupPixmaps();
QHash<const QWindow *, Plasma::FrameSvg::EnabledBorders>::const_iterator i;
for (i = m_windows.constBegin(); i != m_windows.constEnd(); ++i) {
updateShadow(i.key(), i.value());
}
}
Qt::HANDLE PanelShadows::Private::createPixmap(const QPixmap& source)
{
// do nothing for invalid pixmaps
if( source.isNull() ) return 0;
/*
in some cases, pixmap handle is invalid. This is the case notably
when Qt uses to RasterEngine. In this case, we create an X11 Pixmap
explicitly and draw the source pixmap on it.
*/
#if HAVE_X11
if (!m_isX11) {
return 0;
}
// check connection
if( !_connection ) _connection = QX11Info::connection();
const int width( source.width() );
const int height( source.height() );
// create X11 pixmap
Pixmap pixmap = XCreatePixmap( QX11Info::display(), QX11Info::appRootWindow(), width, height, 32 );
// check gc
if( !_gc )
{
_gc = xcb_generate_id( _connection );
xcb_create_gc( _connection, _gc, pixmap, 0, 0x0 );
}
// // create explicitly shared QPixmap from it
// QPixmap dest( QPixmap::fromX11Pixmap( pixmap, QPixmap::ExplicitlyShared ) );
//
// // create surface for pixmap
// {
// QPainter painter( &dest );
// painter.setCompositionMode( QPainter::CompositionMode_Source );
// painter.drawPixmap( 0, 0, source );
// }
//
//
// return pixmap;
QImage image( source.toImage() );
xcb_put_image(
_connection, XCB_IMAGE_FORMAT_Z_PIXMAP, pixmap, _gc,
image.width(), image.height(), 0, 0,
0, 32,
image.byteCount(), image.constBits());
return (Qt::HANDLE)pixmap;
#else
return 0;
#endif
}
void PanelShadows::Private::initPixmap(const QString &element)
{
m_shadowPixmaps << q->pixmap(element);
}
QPixmap PanelShadows::Private::initEmptyPixmap(const QSize &size)
{
#if HAVE_X11
if (!m_isX11) {
return QPixmap();
}
QPixmap tempEmptyPix(size);
if (!size.isEmpty()) {
tempEmptyPix.fill(Qt::transparent);
}
return tempEmptyPix;
#else
Q_UNUSED(size)
return QPixmap();
#endif
}
void PanelShadows::Private::setupPixmaps()
{
clearPixmaps();
initPixmap("shadow-top");
initPixmap("shadow-topright");
initPixmap("shadow-right");
initPixmap("shadow-bottomright");
initPixmap("shadow-bottom");
initPixmap("shadow-bottomleft");
initPixmap("shadow-left");
initPixmap("shadow-topleft");
m_emptyCornerPix = initEmptyPixmap(QSize(1,1));
m_emptyCornerLeftPix = initEmptyPixmap(QSize(q->elementSize("shadow-topleft").width(), 1));
m_emptyCornerTopPix = initEmptyPixmap(QSize(1, q->elementSize("shadow-topleft").height()));
m_emptyCornerRightPix = initEmptyPixmap(QSize(q->elementSize("shadow-bottomright").width(), 1));
m_emptyCornerBottomPix = initEmptyPixmap(QSize(1, q->elementSize("shadow-bottomright").height()));
m_emptyVerticalPix = initEmptyPixmap(QSize(1, q->elementSize("shadow-left").height()));
m_emptyHorizontalPix = initEmptyPixmap(QSize(q->elementSize("shadow-top").width(), 1));
}
void PanelShadows::Private::setupData(Plasma::FrameSvg::EnabledBorders enabledBorders)
{
#if HAVE_X11
if (!m_isX11) {
return;
}
//shadow-top
if (enabledBorders & Plasma::FrameSvg::TopBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_shadowPixmaps[0]));
} else {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyHorizontalPix));
}
//shadow-topright
if (enabledBorders & Plasma::FrameSvg::TopBorder &&
enabledBorders & Plasma::FrameSvg::RightBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_shadowPixmaps[1]));
} else if (enabledBorders & Plasma::FrameSvg::TopBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerTopPix));
} else if (enabledBorders & Plasma::FrameSvg::RightBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerRightPix));
} else {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerPix));
}
//shadow-right
if (enabledBorders & Plasma::FrameSvg::RightBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_shadowPixmaps[2]));
} else {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyVerticalPix));
}
//shadow-bottomright
if (enabledBorders & Plasma::FrameSvg::BottomBorder &&
enabledBorders & Plasma::FrameSvg::RightBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_shadowPixmaps[3]));
} else if (enabledBorders & Plasma::FrameSvg::BottomBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerBottomPix));
} else if (enabledBorders & Plasma::FrameSvg::RightBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerRightPix));
} else {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerPix));
}
//shadow-bottom
if (enabledBorders & Plasma::FrameSvg::BottomBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_shadowPixmaps[4]));
} else {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyHorizontalPix));
}
//shadow-bottomleft
if (enabledBorders & Plasma::FrameSvg::BottomBorder &&
enabledBorders & Plasma::FrameSvg::LeftBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_shadowPixmaps[5]));
} else if (enabledBorders & Plasma::FrameSvg::BottomBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerBottomPix));
} else if (enabledBorders & Plasma::FrameSvg::LeftBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerLeftPix));
} else {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerPix));
}
//shadow-left
if (enabledBorders & Plasma::FrameSvg::LeftBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_shadowPixmaps[6]));
} else {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyVerticalPix));
}
//shadow-topleft
if (enabledBorders & Plasma::FrameSvg::TopBorder &&
enabledBorders & Plasma::FrameSvg::LeftBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_shadowPixmaps[7]));
} else if (enabledBorders & Plasma::FrameSvg::TopBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerTopPix));
} else if (enabledBorders & Plasma::FrameSvg::LeftBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerLeftPix));
} else {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerPix));
}
#endif
int left, top, right, bottom = 0;
QSize marginHint;
if (enabledBorders & Plasma::FrameSvg::TopBorder) {
marginHint = q->elementSize("shadow-hint-top-margin");
if (marginHint.isValid()) {
top = marginHint.height();
} else {
top = m_shadowPixmaps[0].height(); // top
}
} else {
top = 1;
}
if (enabledBorders & Plasma::FrameSvg::RightBorder) {
marginHint = q->elementSize("shadow-hint-right-margin");
if (marginHint.isValid()) {
right = marginHint.width();
} else {
right = m_shadowPixmaps[2].width(); // right
}
} else {
right = 1;
}
if (enabledBorders & Plasma::FrameSvg::BottomBorder) {
marginHint = q->elementSize("shadow-hint-bottom-margin");
if (marginHint.isValid()) {
bottom = marginHint.height();
} else {
bottom = m_shadowPixmaps[4].height(); // bottom
}
} else {
bottom = 1;
}
if (enabledBorders & Plasma::FrameSvg::LeftBorder) {
marginHint = q->elementSize("shadow-hint-left-margin");
if (marginHint.isValid()) {
left = marginHint.width();
} else {
left = m_shadowPixmaps[6].width(); // left
}
} else {
left = 1;
}
data[enabledBorders] << top << right << bottom << left;
}
void PanelShadows::Private::freeX11Pixmaps()
{
#if HAVE_X11
if (!m_isX11) {
return;
}
foreach (const QPixmap &pixmap, m_shadowPixmaps) {
if (!QX11Info::display()) {
return;
}
if (!pixmap.isNull()) {
XFreePixmap(QX11Info::display(), reinterpret_cast<unsigned long>(createPixmap(pixmap)));
}
}
if (!m_emptyCornerPix.isNull()) {
XFreePixmap(QX11Info::display(), reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerPix)));
}
if (!m_emptyCornerBottomPix.isNull()) {
XFreePixmap(QX11Info::display(), reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerBottomPix)));
}
if (!m_emptyCornerLeftPix.isNull()) {
XFreePixmap(QX11Info::display(), reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerLeftPix)));
}
if (!m_emptyCornerRightPix.isNull()) {
XFreePixmap(QX11Info::display(), reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerRightPix)));
}
if (!m_emptyCornerTopPix.isNull()) {
XFreePixmap(QX11Info::display(), reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerTopPix)));
}
if (!m_emptyVerticalPix.isNull()) {
XFreePixmap(QX11Info::display(), reinterpret_cast<unsigned long>(createPixmap(m_emptyVerticalPix)));
}
if (!m_emptyHorizontalPix.isNull()) {
XFreePixmap(QX11Info::display(), reinterpret_cast<unsigned long>(createPixmap(m_emptyHorizontalPix)));
}
#endif
}
void PanelShadows::Private::clearPixmaps()
{
#if HAVE_X11
freeX11Pixmaps();
m_emptyCornerPix = QPixmap();
m_emptyCornerBottomPix = QPixmap();
m_emptyCornerLeftPix = QPixmap();
m_emptyCornerRightPix = QPixmap();
m_emptyCornerTopPix = QPixmap();
m_emptyVerticalPix = QPixmap();
m_emptyHorizontalPix = QPixmap();
#endif
m_shadowPixmaps.clear();
data.clear();
}
void PanelShadows::Private::updateShadow(const QWindow *window, Plasma::FrameSvg::EnabledBorders enabledBorders)
{
#if HAVE_X11
if (!m_isX11) {
return;
}
if (m_shadowPixmaps.isEmpty()) {
setupPixmaps();
}
if (!data.contains(enabledBorders)) {
setupData(enabledBorders);
}
Display *dpy = QX11Info::display();
Atom atom = XInternAtom(dpy, "_KDE_NET_WM_SHADOW", False);
qDebug() << "going to set the shadow of" << window->winId() << "to" << data;
XChangeProperty(dpy, window->winId(), atom, XA_CARDINAL, 32, PropModeReplace,
reinterpret_cast<const unsigned char *>(data[enabledBorders].constData()), data[enabledBorders].size());
#else
Q_UNUSED(window)
Q_UNUSED(enabledBorders)
#endif
}
void PanelShadows::Private::clearShadow(const QWindow *window)
{
#if HAVE_X11
if (!m_isX11) {
return;
}
Display *dpy = QX11Info::display();
Atom atom = XInternAtom(dpy, "_KDE_NET_WM_SHADOW", False);
XDeleteProperty(dpy, window->winId(), atom);
#else
Q_UNUSED(window)
#endif
}
bool PanelShadows::enabled() const
{
return hasElement("shadow-left");
}
#include "moc_panelshadows_p.cpp"

View File

@ -1,52 +0,0 @@
/*
* Copyright 2011 by Aaron Seigo <aseigo@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2,
* 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 Library 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 PLASMA_PANELSHADOWS_H
#define PLASMA_PANELSHADOWS_H
#include <QSet>
#include "plasma/framesvg.h"
#include "plasma/svg.h"
class PanelShadows : public Plasma::Svg
{
Q_OBJECT
public:
explicit PanelShadows(QObject *parent = 0, const QString &prefix = "widgets/panel-background");
~PanelShadows();
static PanelShadows *self();
void addWindow(const QWindow *window, Plasma::FrameSvg::EnabledBorders enabledBorders = Plasma::FrameSvg::AllBorders);
void removeWindow(const QWindow *window);
bool enabled() const;
private:
class Private;
Private * const d;
Q_PRIVATE_SLOT(d, void updateShadows())
Q_PRIVATE_SLOT(d, void windowDestroyed(QObject *deletedObject))
};
#endif

View File

@ -1,757 +0,0 @@
/*
* Copyright 2013 Marco Martin <mart@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 <config-plasma.h>
#include "panelview.h"
#include "shellcorona.h"
#include "panelshadows_p.h"
#include "panelconfigview.h"
#include <QAction>
#include <QApplication>
#include <QDebug>
#include <QDesktopWidget>
#include <QScreen>
#include <QQmlEngine>
#include <QQmlContext>
#include <QTimer>
#include <kactioncollection.h>
#include <kwindowsystem.h>
#include <kwindoweffects.h>
#include <Plasma/Containment>
#include <Plasma/Package>
#if HAVE_X11
#include <xcb/xcb.h>
#include <QX11Info>
#endif
PanelView::PanelView(ShellCorona *corona, QWindow *parent)
: PlasmaQuick::View(corona, parent),
m_offset(0),
m_maxLength(0),
m_minLength(0),
m_distance(0),
m_alignment(Qt::AlignLeft),
m_corona(corona),
m_strutsTimer(new QTimer(this)),
m_visibilityMode(NormalPanel)
{
QSurfaceFormat format;
format.setAlphaBufferSize(8);
setFormat(format);
setClearBeforeRendering(true);
setColor(QColor(Qt::transparent));
setFlags(Qt::FramelessWindowHint|Qt::WindowDoesNotAcceptFocus);
KWindowSystem::setType(winId(), NET::Dock);
setVisible(true);
themeChanged();
connect(&m_theme, &Plasma::Theme::themeChanged, this, &PanelView::themeChanged);
m_positionPaneltimer.setSingleShot(true);
m_positionPaneltimer.setInterval(150);
connect(&m_positionPaneltimer, &QTimer::timeout,
this, [=] () {
restore();
positionPanel();
});
m_unhideTimer.setSingleShot(true);
m_unhideTimer.setInterval(500);
connect(&m_unhideTimer, &QTimer::timeout,
this, &PanelView::updateUnhideTrigger);
//Screen management
connect(this, &QWindow::screenChanged,
this, &PanelView::screenChangedProxy);
connect(this, &QWindow::screenChanged,
this, &PanelView::positionPanel);
connect(screen(), &QScreen::geometryChanged,
this, &PanelView::positionPanel);
connect(this, &PlasmaQuick::View::locationChanged,
&m_positionPaneltimer, [=] () {
m_positionPaneltimer.start();
});
connect(this, &PlasmaQuick::View::containmentChanged,
this, &PanelView::positionPanel);
connect(this, &PlasmaQuick::View::containmentChanged,
this, [=] () {
m_positionPaneltimer.start();
});
if (!m_corona->package().isValid()) {
qWarning() << "Invalid home screen package";
}
m_strutsTimer->setSingleShot(true);
connect(m_strutsTimer, &QTimer::timeout,
this, &PanelView::updateStruts);
connect(QApplication::desktop(), &QDesktopWidget::screenCountChanged,
this, &PanelView::updateStruts);
setResizeMode(PlasmaQuick::View::SizeRootObjectToView);
qmlRegisterType<QScreen>();
engine()->rootContext()->setContextProperty("panel", this);
setSource(QUrl::fromLocalFile(m_corona->package().filePath("views", "Panel.qml")));
PanelShadows::self()->addWindow(this);
}
PanelView::~PanelView()
{
if (containment()) {
config().writeEntry("offset", m_offset);
config().writeEntry("max", m_maxLength);
config().writeEntry("min", m_minLength);
if (formFactor() == Plasma::Types::Vertical) {
config().writeEntry("length", size().height());
config().writeEntry("thickness", size().width());
} else {
config().writeEntry("length", size().width());
config().writeEntry("thickness", size().height());
}
config().writeEntry("alignment", (int)m_alignment);
m_corona->requestApplicationConfigSync();
m_corona->requestApplicationConfigSync();
}
PanelShadows::self()->removeWindow(this);
}
KConfigGroup PanelView::config() const
{
if (!containment()) {
return KConfigGroup();
}
KConfigGroup views(m_corona->applicationConfig(), "PlasmaViews");
views = KConfigGroup(&views, QString("Panel %1").arg(containment()->id()));
if (containment()->formFactor() == Plasma::Types::Vertical) {
return KConfigGroup(&views, "Types::Vertical" + QString::number(screen()->size().height()));
//treat everything else as horizontal
} else {
return KConfigGroup(&views, "Horizontal" + QString::number(screen()->size().width()));
}
}
void PanelView::maximize()
{
int length;
if (containment()->formFactor() == Plasma::Types::Vertical) {
length = screen()->size().height();
} else {
length = screen()->size().width();
}
setOffset(0);
setMinimumLength(length);
setMaximumLength(length);
}
Qt::Alignment PanelView::alignment() const
{
return m_alignment;
}
void PanelView::setAlignment(Qt::Alignment alignment)
{
if (m_alignment == alignment) {
return;
}
m_alignment = alignment;
config().writeEntry("alignment", (int)m_alignment);
emit alignmentChanged();
positionPanel();
}
int PanelView::offset() const
{
return m_offset;
}
void PanelView::setOffset(int offset)
{
if (m_offset == offset) {
return;
}
if (formFactor() == Plasma::Types::Vertical) {
if (offset + m_maxLength > screen()->size().height()) {
setMaximumLength( -m_offset + screen()->size().height() );
}
} else {
if (offset + m_maxLength > screen()->size().width()) {
setMaximumLength( -m_offset + screen()->size().width() );
}
}
m_offset = offset;
config().writeEntry("offset", m_offset);
positionPanel();
emit offsetChanged();
m_corona->requestApplicationConfigSync();
m_strutsTimer->start(STRUTSTIMERDELAY);
}
int PanelView::thickness() const
{
return config().readEntry<int>("thickness", 30);
}
void PanelView::setThickness(int value)
{
if (value == thickness()) {
return;
}
config().writeEntry("thickness", value);
m_corona->requestApplicationConfigSync();
positionPanel();
}
int PanelView::length() const
{
return config().readEntry<int>("length",
formFactor() == Plasma::Types::Vertical ?
screen()->size().height() :
screen()->size().width()
);
}
void PanelView::setLength(int value)
{
if (value == length()) {
return;
}
config().writeEntry("length", value);
m_corona->requestApplicationConfigSync();
positionPanel();
}
int PanelView::maximumLength() const
{
return m_maxLength;
}
void PanelView::setMaximumLength(int length)
{
if (length == m_maxLength) {
return;
}
if (m_minLength > length) {
setMinimumLength(length);
}
if (formFactor() == Plasma::Types::Vertical) {
setMaximumHeight(length);
} else {
setMaximumWidth(length);
}
config().writeEntry("maxLength", length);
m_maxLength = length;
emit maximumLengthChanged();
positionPanel();
m_corona->requestApplicationConfigSync();
}
int PanelView::minimumLength() const
{
return m_minLength;
}
void PanelView::setMinimumLength(int length)
{
if (length == m_minLength) {
return;
}
if (m_maxLength < length) {
setMaximumLength(length);
}
if (formFactor() == Plasma::Types::Vertical) {
setMinimumHeight(length);
} else {
setMinimumWidth(length);
}
config().writeEntry("minLength", length);
m_minLength = length;
positionPanel();
emit minimumLengthChanged();
m_corona->requestApplicationConfigSync();
}
int PanelView::distance() const
{
return m_distance;
}
void PanelView::setDistance(int dist)
{
if (m_distance == dist) {
return;
}
m_distance = dist;
emit distanceChanged();
positionPanel();
}
void PanelView::setVisibilityMode(PanelView::VisibilityMode mode)
{
m_visibilityMode = mode;
if (mode == LetWindowsCover) {
KWindowSystem::setState(winId(), NET::KeepBelow);
} else {
KWindowSystem::clearState(winId(), NET::KeepBelow);
}
//life is vastly simpler if we ensure we're visible now
show();
disconnect(containment(), &Plasma::Applet::activated, this, &PanelView::unhide);
if (!(mode == NormalPanel || mode == WindowsGoBelow)) {
connect(containment(), &Plasma::Applet::activated, this, &PanelView::unhide);
}
config().writeEntry("panelVisibility", (int)mode);
updateStruts();
KWindowSystem::setOnAllDesktops(winId(), true);
emit visibilityModeChanged();
updateUnhideTrigger();
}
PanelView::VisibilityMode PanelView::visibilityMode() const
{
return m_visibilityMode;
}
void PanelView::positionPanel()
{
if (!containment()) {
return;
}
QScreen *s = screen();
QPoint position;
switch (containment()->location()) {
case Plasma::Types::TopEdge:
containment()->setFormFactor(Plasma::Types::Horizontal);
switch (m_alignment) {
case Qt::AlignCenter:
position = QPoint(QPoint(s->geometry().center().x(), s->geometry().top()) + QPoint(m_offset - size().width()/2, m_distance));
break;
case Qt::AlignRight:
position = QPoint(s->geometry().topRight() - QPoint(m_offset + size().width(), m_distance));
break;
case Qt::AlignLeft:
default:
position = QPoint(s->geometry().topLeft() + QPoint(m_offset, m_distance));
}
break;
case Plasma::Types::LeftEdge:
containment()->setFormFactor(Plasma::Types::Vertical);
switch (m_alignment) {
case Qt::AlignCenter:
position = QPoint(QPoint(s->geometry().left(), s->geometry().center().y()) + QPoint(m_distance, m_offset));
break;
case Qt::AlignRight:
position = QPoint(s->geometry().bottomLeft() - QPoint(m_distance, m_offset + size().height()));
break;
case Qt::AlignLeft:
default:
position = QPoint(s->geometry().topLeft() + QPoint(m_distance, m_offset));
}
break;
case Plasma::Types::RightEdge:
containment()->setFormFactor(Plasma::Types::Vertical);
switch (m_alignment) {
case Qt::AlignCenter:
position = QPoint(QPoint(s->geometry().right(), s->geometry().center().y()) - QPoint(width() + m_distance, 0) + QPoint(0, m_offset - size().height()/2));
break;
case Qt::AlignRight:
position = QPoint(s->geometry().bottomRight() - QPoint(width() + m_distance, 0) - QPoint(0, m_offset + size().height()));
break;
case Qt::AlignLeft:
default:
position = QPoint(s->geometry().topRight() - QPoint(width() + m_distance, 0) + QPoint(0, m_offset));
}
break;
case Plasma::Types::BottomEdge:
default:
containment()->setFormFactor(Plasma::Types::Horizontal);
switch (m_alignment) {
case Qt::AlignCenter:
position = QPoint(QPoint(s->geometry().center().x(), s->geometry().bottom() - height() - m_distance) + QPoint(m_offset - size().width()/2, 1));
break;
case Qt::AlignRight:
position = QPoint(s->geometry().bottomRight() - QPoint(0, height() + m_distance) - QPoint(m_offset + size().width(), 1));
break;
case Qt::AlignLeft:
default:
position = QPoint(s->geometry().bottomLeft() - QPoint(0, height() + m_distance) + QPoint(m_offset, 1));
}
}
m_strutsTimer->stop();
m_strutsTimer->start(STRUTSTIMERDELAY);
setMinimumSize(QSize(0, 0));
setMaximumSize(screen()->size());
if (formFactor() == Plasma::Types::Vertical) {
setGeometry(QRect(position, QSize(thickness(), length())));
setMinimumSize(QSize(thickness(), m_minLength));
setMaximumSize(QSize(thickness(), m_maxLength));
emit thicknessChanged();
emit length();
} else {
setGeometry(QRect(position, QSize(length(), thickness())));
setMinimumSize(QSize(m_minLength, thickness()));
setMaximumSize(QSize(m_maxLength, thickness()));
emit thicknessChanged();
emit length();
}
updateUnhideTrigger();
}
void PanelView::restore()
{
if (!containment()) {
return;
}
connect(containment(), SIGNAL(destroyed(QObject *)),
this, SLOT(deleteLater()));
static const int MINSIZE = 10;
m_offset = config().readEntry<int>("offset", 0);
if (m_alignment != Qt::AlignCenter) {
m_offset = qMax(0, m_offset);
}
m_alignment = (Qt::Alignment)config().readEntry<int>("alignment", Qt::AlignLeft);
setMinimumSize(QSize(-1, -1));
//FIXME: an invalid size doesn't work with QWindows
setMaximumSize(screen()->size());
if (containment()->formFactor() == Plasma::Types::Vertical) {
m_maxLength = config().readEntry<int>("maxLength", screen()->size().height());
m_minLength = config().readEntry<int>("minLength", screen()->size().height());
const int maxSize = screen()->size().height() - m_offset;
m_maxLength = qBound<int>(MINSIZE, m_maxLength, maxSize);
m_minLength = qBound<int>(MINSIZE, m_minLength, maxSize);
resize(thickness(), qBound<int>(MINSIZE, length(), maxSize));
setMinimumHeight(m_minLength);
setMaximumHeight(m_maxLength);
//Horizontal
} else {
m_maxLength = config().readEntry<int>("maxLength", screen()->size().width());
m_minLength = config().readEntry<int>("minLength", screen()->size().width());
const int maxSize = screen()->size().width() - m_offset;
m_maxLength = qBound<int>(MINSIZE, m_maxLength, maxSize);
m_minLength = qBound<int>(MINSIZE, m_minLength, maxSize);
resize(qBound<int>(MINSIZE, length(), maxSize), thickness());
setMinimumWidth(m_minLength);
setMaximumWidth(m_maxLength);
}
setVisibilityMode((VisibilityMode)config().readEntry<int>("panelVisibility", (int)NormalPanel));
emit maximumLengthChanged();
emit minimumLengthChanged();
emit offsetChanged();
emit alignmentChanged();
}
void PanelView::showConfigurationInterface(Plasma::Applet *applet)
{
if (m_panelConfigView) {
m_panelConfigView.data()->hide();
m_panelConfigView.data()->deleteLater();
return;
}
if (!applet || !applet->containment()) {
return;
}
Plasma::Containment *cont = qobject_cast<Plasma::Containment *>(applet);
if (cont) {
m_panelConfigView = new PanelConfigView(cont, this);
} else {
m_panelConfigView = new PlasmaQuick::ConfigView(applet);
}
m_panelConfigView.data()->init();
m_panelConfigView.data()->show();
KWindowSystem::setState(m_panelConfigView.data()->winId(), NET::SkipTaskbar | NET::SkipPager);
}
void PanelView::updateUnhideTrigger()
{
#if HAVE_X11
xcb_connection_t *c = QX11Info::connection();
if (!c) {
return;
}
const QByteArray effectName = QByteArrayLiteral("_KDE_NET_WM_SCREEN_EDGE_SHOW");
xcb_intern_atom_cookie_t atomCookie = xcb_intern_atom_unchecked(c, false, effectName.length(), effectName.constData());
QScopedPointer<xcb_intern_atom_reply_t, QScopedPointerPodDeleter> atom(xcb_intern_atom_reply(c, atomCookie, NULL));
if (!atom) {
return;
}
if (m_visibilityMode != AutoHide) {
xcb_delete_property(c, winId(), atom->atom);
return;
}
KWindowEffects::SlideFromLocation slideLocation = KWindowEffects::NoEdge;
uint32_t value = 0;
switch (location()) {
case Plasma::Types::TopEdge:
value = 0;
slideLocation = KWindowEffects::TopEdge;
break;
case Plasma::Types::RightEdge:
value = 1;
slideLocation = KWindowEffects::RightEdge;
break;
case Plasma::Types::BottomEdge:
value = 2;
slideLocation = KWindowEffects::BottomEdge;
break;
case Plasma::Types::LeftEdge:
value = 3;
slideLocation = KWindowEffects::LeftEdge;
break;
case Plasma::Types::Floating:
default:
value = 4;
break;
}
KWindowEffects::slideWindow(winId(), slideLocation, -1);
xcb_change_property(c, XCB_PROP_MODE_REPLACE, winId(), atom->atom, XCB_ATOM_CARDINAL, 32, 1, &value);
#endif
}
void PanelView::resizeEvent(QResizeEvent *ev)
{
if (containment()->formFactor() == Plasma::Types::Vertical) {
config().writeEntry("length", ev->size().height());
config().writeEntry("thickness", ev->size().width());
if (ev->size().height() != ev->oldSize().height()) {
emit lengthChanged();
}
if (ev->size().width() != ev->oldSize().width()) {
emit thicknessChanged();
}
} else {
config().writeEntry("length", ev->size().width());
config().writeEntry("thickness", ev->size().height());
if (ev->size().width() != ev->oldSize().width()) {
emit lengthChanged();
}
if (ev->size().height() != ev->oldSize().height()) {
emit thicknessChanged();
}
}
m_positionPaneltimer.start();
PlasmaQuick::View::resizeEvent(ev);
}
void PanelView::showEvent(QShowEvent *event)
{
PanelShadows::self()->addWindow(this);
PlasmaQuick::View::showEvent(event);
KWindowSystem::setOnAllDesktops(winId(), true);
}
bool PanelView::event(QEvent *e)
{
if (e->type() == QEvent::Enter) {
m_unhideTimer.stop();
} else if (e->type() == QEvent::Leave) {
m_unhideTimer.start();
}
return View::event(e);
}
void PanelView::unhide()
{
m_unhideTimer.start();
}
void PanelView::updateStruts()
{
if (!containment() || !screen()) {
return;
}
NETExtendedStrut strut;
if (m_visibilityMode == NormalPanel) {
const QRect thisScreen = corona()->screenGeometry(containment()->screen());
const QRect wholeScreen = screen()->virtualGeometry();
//Extended struts against a screen edge near to another screen are really harmful, so windows maximized under the panel is a lesser pain
//TODO: force "windows can cover" in those cases?
const int numScreens = corona()->numScreens();
for (int i = 0; i < numScreens; ++i) {
if (i == containment()->screen()) {
continue;
}
const QRect otherScreen = corona()->screenGeometry(i);
switch (location())
{
case Plasma::Types::TopEdge:
if (otherScreen.bottom() <= thisScreen.top()) {
KWindowSystem::setExtendedStrut(winId(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
return;
}
break;
case Plasma::Types::BottomEdge:
if (otherScreen.top() >= thisScreen.bottom()) {
KWindowSystem::setExtendedStrut(winId(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
return;
}
break;
case Plasma::Types::RightEdge:
if (otherScreen.left() >= thisScreen.right()) {
KWindowSystem::setExtendedStrut(winId(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
return;
}
break;
case Plasma::Types::LeftEdge:
if (otherScreen.right() <= thisScreen.left()) {
KWindowSystem::setExtendedStrut(winId(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
return;
}
break;
default:
return;
}
}
// extended struts are to the combined screen geoms, not the single screen
int leftOffset = wholeScreen.x() - thisScreen.x();
int rightOffset = wholeScreen.right() - thisScreen.right();
int bottomOffset = wholeScreen.bottom() - thisScreen.bottom();
int topOffset = wholeScreen.top() - thisScreen.top();
// qDebug() << "screen l/r/b/t offsets are:" << leftOffset << rightOffset << bottomOffset << topOffset << location();
switch (location())
{
case Plasma::Types::TopEdge:
strut.top_width = thickness() + topOffset;
strut.top_start = x();
strut.top_end = x() + width() - 1;
// qDebug() << "setting top edge to" << strut.top_width << strut.top_start << strut.top_end;
break;
case Plasma::Types::BottomEdge:
strut.bottom_width = thickness() + bottomOffset;
strut.bottom_start = x();
strut.bottom_end = x() + width() - 1;
// qDebug() << "setting bottom edge to" << strut.bottom_width << strut.bottom_start << strut.bottom_end;
break;
case Plasma::Types::RightEdge:
strut.right_width = thickness() + rightOffset;
strut.right_start = y();
strut.right_end = y() + height() - 1;
// qDebug() << "setting right edge to" << strut.right_width << strut.right_start << strut.right_end;
break;
case Plasma::Types::LeftEdge:
strut.left_width = thickness() + leftOffset;
strut.left_start = y();
strut.left_end = y() + height() - 1;
// qDebug() << "setting left edge to" << strut.left_width << strut.left_start << strut.left_end;
break;
default:
//qDebug() << "where are we?";
break;
}
}
KWindowSystem::setExtendedStrut(winId(), strut.left_width,
strut.left_start,
strut.left_end,
strut.right_width,
strut.right_start,
strut.right_end,
strut.top_width,
strut.top_start,
strut.top_end,
strut.bottom_width,
strut.bottom_start,
strut.bottom_end);
//recreateUnhideTrigger();
}
void PanelView::themeChanged()
{
//TODO: how to take the shape from the framesvg?
KWindowEffects::enableBlurBehind(winId(), true);
KWindowEffects::enableBackgroundContrast(winId(), m_theme.backgroundContrastEnabled(),
m_theme.backgroundContrast(),
m_theme.backgroundIntensity(),
m_theme.backgroundSaturation());
}
#include "moc_panelview.cpp"

View File

@ -1,137 +0,0 @@
/*
* Copyright 2013 Marco Martin <mart@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 PANELVIEW_H
#define PANELVIEW_H
#include <view.h>
#include <QtCore/qpointer.h>
#include <Plasma/Theme>
#include <QTimer>
#include <configview.h>
class ShellCorona;
class PanelView : public PlasmaQuick::View
{
Q_OBJECT
Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment NOTIFY alignmentChanged)
Q_PROPERTY(int offset READ offset WRITE setOffset NOTIFY offsetChanged)
Q_PROPERTY(int thickness READ thickness WRITE setThickness NOTIFY thicknessChanged)
Q_PROPERTY(int length READ length WRITE setLength NOTIFY lengthChanged)
Q_PROPERTY(int maximumLength READ maximumLength WRITE setMaximumLength NOTIFY maximumLengthChanged)
Q_PROPERTY(int minimumLength READ minimumLength WRITE setMinimumLength NOTIFY minimumLengthChanged)
Q_PROPERTY(int distance READ distance WRITE setDistance NOTIFY distanceChanged)
Q_PROPERTY(QScreen *screen READ screen WRITE setScreen NOTIFY screenChangedProxy)
Q_PROPERTY(VisibilityMode visibilityMode READ visibilityMode WRITE setVisibilityMode NOTIFY visibilityModeChanged)
public:
enum VisibilityMode {
NormalPanel = 0,
AutoHide,
LetWindowsCover,
WindowsGoBelow
};
Q_ENUMS(VisibilityMode)
explicit PanelView(ShellCorona *corona, QWindow *parent = 0);
virtual ~PanelView();
virtual KConfigGroup config() const;
Q_INVOKABLE void maximize();
Qt::Alignment alignment() const;
void setAlignment(Qt::Alignment alignment);
int offset() const;
void setOffset(int offset);
int thickness() const;
void setThickness(int thickness);
int length() const;
void setLength(int value);
int maximumLength() const;
void setMaximumLength(int length);
int minimumLength() const;
void setMinimumLength(int length);
int distance() const;
void setDistance(int dist);
VisibilityMode visibilityMode() const;
void setVisibilityMode(PanelView::VisibilityMode mode);
protected:
void resizeEvent(QResizeEvent *ev);
void showEvent(QShowEvent *event);
bool event(QEvent *e);
Q_SIGNALS:
void alignmentChanged();
void offsetChanged();
void screenGeometryChanged();
void thicknessChanged();
void lengthChanged();
void maximumLengthChanged();
void minimumLengthChanged();
void distanceChanged();
//QWindow does not have a property for screen. Adding this property requires re-implementing the signal
void screenChangedProxy(QScreen *screen);
void visibilityModeChanged();
protected Q_SLOTS:
/**
* It will be called when the configuration is requested
*/
virtual void showConfigurationInterface(Plasma::Applet *applet);
void updateStruts();
private Q_SLOTS:
void themeChanged();
void positionPanel();
void restore();
void updateUnhideTrigger();
void unhide();
private:
int m_offset;
int m_maxLength;
int m_minLength;
int m_distance;
Qt::Alignment m_alignment;
QPointer<PlasmaQuick::ConfigView> m_panelConfigView;
ShellCorona *m_corona;
QTimer *m_strutsTimer;
VisibilityMode m_visibilityMode;
Plasma::Theme m_theme;
QTimer m_positionPaneltimer;
QTimer m_unhideTimer;
static const int STRUTSTIMERDELAY = 200;
};
#endif // PANELVIEW_H

View File

@ -1,22 +0,0 @@
[Desktop Entry]
Exec=plasma-shell --shut-up
X-DBUS-StartupType=Unique
Name=Plasma Desktop Workspace
Name[cs]=Pracovní plocha Plasma
Name[de]=Plasma-Arbeitsflächenbereich
Name[fi]=Plasma-työpöytä
Name[fr]=Espace de travail du bureau Plasma
Name[hu]=Plazma asztali munkaterület
Name[nl]=Plasma Bureaublad Werkplek
Name[pl]=Przestrzeń robocza pulpitu Plazmy
Name[pt]=Área de Trabalho do Plasma
Name[pt_BR]=Espaço de Trabalho Plasma
Name[sk]=Pracovná plocha Plasma
Name[sv]=Plasma arbetsområde för skrivbordet
Name[uk]=Робочий простір стільниці Плазми
Name[x-test]=xxPlasma Desktop Workspacexx
Type=Application
X-KDE-StartupNotify=false
X-DBUS-ServiceName=org.kde.plasma_shell
OnlyShowIn=KDE;
X-KDE-autostart-phase=0

View File

@ -1,216 +0,0 @@
/*
* Copyright 2009 Aaron Seigo <aseigo@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 "appinterface.h"
#include <QEventLoop>
#include <QTimer>
#include <solid/device.h>
#include <Plasma/Containment>
#include <Plasma/Corona>
#include <Plasma/DataEngine>
#include <Plasma/DataEngineConsumer>
#include <Plasma/PluginLoader>
#include <Plasma/Theme>
#ifdef Q_OS_WIN
#include <windows.h>
#endif
#ifdef Q_WS_X11
#include <X11/Xlib.h>
#include <fixx11h.h>
#endif
#include "scriptengine.h"
namespace WorkspaceScripting
{
AppInterface::AppInterface(ScriptEngine *env)
: QObject(env),
m_env(env)
{
m_theme = new Plasma::Theme(this);
}
int AppInterface::screenCount() const
{
return m_env->corona()->numScreens();
}
QRectF AppInterface::screenGeometry(int screen) const
{
return m_env->corona()->screenGeometry(screen);
}
QList<int> AppInterface::activityIds() const
{
//FIXME: the ints could overflow since Applet::id() returns a uint,
// however QScript deals with QList<uint> very, very poorly
QList<int> containments;
foreach (Plasma::Containment *c, m_env->corona()->containments()) {
if (!ScriptEngine::isPanel(c)) {
containments.append(c->id());
}
}
return containments;
}
QList<int> AppInterface::panelIds() const
{
//FIXME: the ints could overflow since Applet::id() returns a uint,
// however QScript deals with QList<uint> very, very poorly
QList<int> panels;
foreach (Plasma::Containment *c, m_env->corona()->containments()) {
//qDebug() << "checking" << (QObject*)c << isPanel(c);
if (ScriptEngine::isPanel(c)) {
panels.append(c->id());
}
}
return panels;
}
QString AppInterface::applicationVersion() const
{
return qApp->applicationVersion();
}
QString AppInterface::platformVersion() const
{
return 0;//KDE::versionString();
}
int AppInterface::scriptingVersion() const
{
return PLASMA_DESKTOP_SCRIPTING_VERSION;
}
QString AppInterface::theme() const
{
return m_theme->themeName();
}
void AppInterface::setTheme(const QString &name)
{
m_theme->setThemeName(name);
}
bool AppInterface::multihead() const
{
#ifdef Q_OS_WIN
return GetSystemMetrics(SM_CMONITORS) > 1;
#else
QByteArray multiHead = qgetenv("KDE_MULTIHEAD");
if (!multiHead.isEmpty()) {
return (multiHead.toLower() == "true");
}
return false;
#endif
}
int AppInterface::multiheadScreen() const
{
int id = -1;
#ifdef Q_WS_X11
if (multihead()) {
// with multihead, we "lie" and say that screen 0 is the default screen, in fact, we pretend
// we have only one screen at all
Display *dpy = XOpenDisplay(NULL);
if (dpy) {
id = DefaultScreen(dpy);
XCloseDisplay(dpy);
}
}
#endif
return id;
}
void AppInterface::lockCorona(bool locked)
{
m_env->corona()->setImmutability(locked ? Plasma::Types::UserImmutable : Plasma::Types::Mutable);
}
bool AppInterface::coronaLocked() const
{
return m_env->corona()->immutability() != Plasma::Types::Mutable;
}
void AppInterface::sleep(int ms)
{
QEventLoop loop;
QTimer::singleShot(ms, &loop, SLOT(quit()));
loop.exec(QEventLoop::ExcludeUserInputEvents);
}
bool AppInterface::hasBattery() const
{
return !Solid::Device::listFromType(Solid::DeviceInterface::Battery).isEmpty();
}
QStringList AppInterface::knownWidgetTypes() const
{
if (m_knownWidgets.isEmpty()) {
QStringList widgets;
KPluginInfo::List infoLs = Plasma::PluginLoader::self()->listAppletInfo(QString());
foreach (const KPluginInfo &info, infoLs) {
widgets.append(info.pluginName());
}
const_cast<AppInterface *>(this)->m_knownWidgets = widgets;
}
return m_knownWidgets;
}
QStringList AppInterface::knownActivityTypes() const
{
return knownContainmentTypes("desktop");
}
QStringList AppInterface::knownPanelTypes() const
{
return knownContainmentTypes("panel");
}
QStringList AppInterface::knownContainmentTypes(const QString &type) const
{
QStringList containments;
KPluginInfo::List infoLs = Plasma::PluginLoader::listContainmentsOfType(type);
foreach (const KPluginInfo &info, infoLs) {
containments.append(info.pluginName());
}
return containments;
}
}
#include "appinterface.moc"

View File

@ -1,100 +0,0 @@
/*
* Copyright 2009 Aaron Seigo <aseigo@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 APPINTERFACE
#define APPINTERFACE
#include <QObject>
#include <QRectF>
#include <QStringList>
namespace Plasma
{
class Applet;
class Containment;
class Corona;
class Theme;
} // namespace Plasma
namespace WorkspaceScripting
{
class ScriptEngine;
class AppInterface : public QObject
{
Q_OBJECT
Q_PROPERTY(bool locked READ coronaLocked WRITE lockCorona)
Q_PROPERTY(bool hasBattery READ hasBattery)
Q_PROPERTY(int screenCount READ screenCount)
Q_PROPERTY(QList<int> activityIds READ activityIds)
Q_PROPERTY(QList<int> panelIds READ panelIds)
Q_PROPERTY(QStringList knownPanelTypes READ knownPanelTypes)
Q_PROPERTY(QStringList knownActivityTypes READ knownActivityTypes)
Q_PROPERTY(QStringList knownWidgetTypes READ knownWidgetTypes)
Q_PROPERTY(QString theme READ theme WRITE setTheme)
Q_PROPERTY(QString applicationVersion READ applicationVersion)
Q_PROPERTY(QString platformVersion READ platformVersion)
Q_PROPERTY(int scriptingVersion READ scriptingVersion)
Q_PROPERTY(bool multihead READ multihead)
Q_PROPERTY(bool multiheadScreen READ multihead)
public:
AppInterface(ScriptEngine *env);
bool hasBattery() const;
int screenCount() const;
QList<int> activityIds() const;
QList<int> panelIds() const;
QStringList knownWidgetTypes() const;
QStringList knownActivityTypes() const;
QStringList knownPanelTypes() const;
QStringList knownContainmentTypes(const QString &type) const;
QString applicationVersion() const;
QString platformVersion() const;
int scriptingVersion() const;
QString theme() const;
void setTheme(const QString &name);
bool multihead() const;
int multiheadScreen() const;
bool coronaLocked() const;
public Q_SLOTS:
QRectF screenGeometry(int screen) const;
void lockCorona(bool locked);
void sleep(int ms);
Q_SIGNALS:
void print(const QString &string);
private:
ScriptEngine *m_env;
QStringList m_knownWidgets;
Plasma::Theme *m_theme;
};
}
#endif

View File

@ -1,269 +0,0 @@
/*
* Copyright 2009 Aaron Seigo <aseigo@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 "applet.h"
#include <QAction>
#include <kservice.h>
#include <kservicetypetrader.h>
#include <Plasma/Applet>
#include <Plasma/Containment>
#include <Plasma/Corona>
namespace WorkspaceScripting
{
class Applet::Private
{
public:
Private()
: configDirty(false),
inWallpaperConfig(false),
wallpaperConfigDirty(false)
{
}
KConfigGroup configGroup;
QStringList configGroupPath;
KConfigGroup globalConfigGroup;
QStringList globalConfigGroupPath;
bool configDirty : 1;
bool inWallpaperConfig : 1;
bool wallpaperConfigDirty : 1;
};
Applet::Applet(QObject *parent)
: QObject(parent),
d(new Applet::Private)
{
}
Applet::~Applet()
{
delete d;
}
void Applet::setCurrentConfigGroup(const QStringList &groupNames)
{
Plasma::Applet *app = applet();
if (!app) {
d->configGroup = KConfigGroup();
d->configGroupPath.clear();
return;
}
d->configGroup = app->config();
d->configGroupPath = groupNames;
foreach (const QString &groupName, groupNames) {
d->configGroup = KConfigGroup(&d->configGroup, groupName);
}
d->inWallpaperConfig = !groupNames.isEmpty() && groupNames.first() == "Wallpaper";
}
QStringList Applet::currentConfigGroup() const
{
return d->configGroupPath;
}
QStringList Applet::configKeys() const
{
if (d->configGroup.isValid()) {
return d->configGroup.keyList();
}
return QStringList();
}
QStringList Applet::configGroups() const
{
if (d->configGroup.isValid()) {
return d->configGroup.groupList();
}
return QStringList();
}
QVariant Applet::readConfig(const QString &key, const QVariant &def) const
{
if (d->configGroup.isValid()) {
return d->configGroup.readEntry(key, def);
} else {
return QVariant();
}
}
void Applet::writeConfig(const QString &key, const QVariant &value)
{
if (d->configGroup.isValid()) {
if (d->inWallpaperConfig) {
d->wallpaperConfigDirty = true;
}
d->configGroup.writeEntry(key, value);
d->configDirty = true;
}
}
void Applet::setCurrentGlobalConfigGroup(const QStringList &groupNames)
{
Plasma::Applet *app = applet();
if (!app) {
d->globalConfigGroup = KConfigGroup();
d->globalConfigGroupPath.clear();
return;
}
d->globalConfigGroup = app->globalConfig();
d->globalConfigGroupPath = groupNames;
foreach (const QString &groupName, groupNames) {
d->globalConfigGroup = KConfigGroup(&d->globalConfigGroup, groupName);
}
}
QStringList Applet::currentGlobalConfigGroup() const
{
return d->globalConfigGroupPath;
}
QStringList Applet::globalConfigKeys() const
{
if (d->globalConfigGroup.isValid()) {
return d->globalConfigGroup.keyList();
}
return QStringList();
}
QStringList Applet::globalConfigGroups() const
{
if (d->globalConfigGroup.isValid()) {
return d->globalConfigGroup.groupList();
}
return QStringList();
}
QVariant Applet::readGlobalConfig(const QString &key, const QVariant &def) const
{
if (d->globalConfigGroup.isValid()) {
return d->globalConfigGroup.readEntry(key, def);
} else {
return QVariant();
}
}
void Applet::writeGlobalConfig(const QString &key, const QVariant &value)
{
if (d->globalConfigGroup.isValid()) {
d->globalConfigGroup.writeEntry(key, value);
d->configDirty = true;
}
}
void Applet::reloadConfigIfNeeded()
{
if (d->configDirty) {
reloadConfig();
}
}
void Applet::reloadConfig()
{
Plasma::Applet *app = applet();
if (app) {
KConfigGroup cg = app->config();
if (!app->isContainment()) {
app->restore(cg);
}
app->configChanged();
if (app->containment() && app->containment()->corona()) {
app->containment()->corona()->requestConfigSync();
}
d->configDirty = false;
}
}
QString Applet::version() const
{
Plasma::Applet *app = applet();
if (!app) {
return QString();
}
QString type = app->pluginInfo().pluginName();
KService::List services = KServiceTypeTrader::self()->query("Plasma/Applet", "[X-KDE-PluginInfo-Name] == '" + type + "'");
if (services.isEmpty()) {
return QString();
}
KPluginInfo info(services.first());
return info.version();
}
void Applet::setLocked(bool locked)
{
Plasma::Applet *app = applet();
if (!app) {
return;
}
app->setImmutability(locked ? Plasma::Types::UserImmutable : Plasma::Types::Mutable);
KConfigGroup cg = app->config();
if (!app->isContainment()) {
cg = cg.parent();
}
if (cg.isValid()) {
cg.writeEntry("immutability", (int)app->immutability());
}
}
bool Applet::locked() const
{
Plasma::Applet *app = applet();
if (!app) {
return Plasma::Types::Mutable;
}
return app->immutability() != Plasma::Types::Mutable;
}
bool Applet::wallpaperConfigDirty() const
{
return d->wallpaperConfigDirty;
}
Plasma::Applet *Applet::applet() const
{
return 0;
}
}
#include "applet.moc"

View File

@ -1,84 +0,0 @@
/*
* Copyright 2010 Aaron Seigo <aseigo@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 APPLET
#define APPLET
#include <QObject>
#include <QWeakPointer>
#include <kconfiggroup.h>
namespace Plasma
{
class Applet;
} // namespace Plasma
namespace WorkspaceScripting
{
class Applet : public QObject
{
Q_OBJECT
public:
Applet(QObject *parent = 0);
~Applet();
QStringList configKeys() const;
QStringList configGroups() const;
void setCurrentConfigGroup(const QStringList &groupNames);
QStringList currentConfigGroup() const;
QStringList globalConfigKeys() const;
QStringList globalConfigGroups() const;
void setCurrentGlobalConfigGroup(const QStringList &groupNames);
QStringList currentGlobalConfigGroup() const;
QString version() const;
void setLocked(bool locked);
bool locked() const;
bool wallpaperConfigDirty() const;
virtual Plasma::Applet *applet() const;
protected:
void reloadConfigIfNeeded();
public Q_SLOTS:
virtual QVariant readConfig(const QString &key, const QVariant &def = QString()) const;
virtual void writeConfig(const QString &key, const QVariant &value);
virtual QVariant readGlobalConfig(const QString &key, const QVariant &def = QString()) const;
virtual void writeGlobalConfig(const QString &key, const QVariant &value);
virtual void reloadConfig();
private:
class Private;
Private * const d;
};
}
#endif

View File

@ -1,349 +0,0 @@
/****************************************************************************
**
** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.
**
** This file is part of the plugins of the Qt Toolkit.
**
** This file may be used under the terms of the GNU General Public
** License version 2.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of
** this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
** http://trolltech.com/products/qt/licenses/licensing/opensource/
**
** If you are unsure which license is appropriate for your use, please
** review the following information:
** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
** or contact the sales department at sales@trolltech.com.
**
** In addition, as a special exception, Trolltech gives you certain
** additional rights. These rights are described in the Trolltech GPL
** Exception version 1.0, which can be found at
** http://www.trolltech.com/products/qt/gplexception/ and in the file
** GPL_EXCEPTION.txt in this package.
**
** In addition, as a special exception, Trolltech, as the sole copyright
** holder for Qt Designer, grants users of the Qt/Eclipse Integration
** plug-in the right for the Qt/Eclipse Integration to link to
** functionality provided by Qt Designer and its related libraries.
**
** Trolltech reserves all rights not expressly granted herein.
**
** Trolltech ASA (c) 2007
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
#ifndef QTSCRIPTEXTENSIONS_GLOBAL_H
#define QTSCRIPTEXTENSIONS_GLOBAL_H
#include <QtCore/QSharedData>
#define DECLARE_SELF(Class, __fn__) \
Class* self = qscriptvalue_cast<Class*>(ctx->thisObject()); \
if (!self) { \
return ctx->throwError(QScriptContext::TypeError, \
QString::fromLatin1("%0.prototype.%1: this object is not a %0") \
.arg(#Class).arg(#__fn__)); \
}
#define DECLARE_SELF2(Class, __fn__, __ret__) \
Class* self = qscriptvalue_cast<Class*>(thisObject()); \
if (!self) { \
context()->throwError(QScriptContext::TypeError, \
QString::fromLatin1("%0.prototype.%1: this object is not a %0") \
.arg(#Class).arg(#__fn__)); \
return __ret__; \
}
#define ADD_METHOD(__p__, __f__) \
__p__.setProperty(#__f__, __p__.engine()->newFunction(__f__))
#define ADD_GET_METHOD(__p__, __get__) \
ADD_METHOD(__p__, __get__)
#define ADD_GET_SET_METHODS(__p__, __get__, __set__) \
do { \
ADD_METHOD(__p__, __get__); \
ADD_METHOD(__p__, __set__); \
} while (0);
#define ADD_CTOR_FUNCTION(__c__, __f__) ADD_METHOD(__c__, __f__)
#define ADD_ENUM_VALUE(__c__, __ns__, __v__) \
__c__.setProperty(#__v__, QScriptValue(__c__.engine(), __ns__::__v__))
#define BEGIN_DECLARE_METHOD(Class, __mtd__) \
static QScriptValue __mtd__(QScriptContext *ctx, QScriptEngine *eng) \
{ \
DECLARE_SELF(Class, __mtd__);
#define END_DECLARE_METHOD \
}
#define DECLARE_GET_METHOD(Class, __get__) \
BEGIN_DECLARE_METHOD(Class, __get__) { \
return qScriptValueFromValue(eng, self->__get__()); \
} END_DECLARE_METHOD
#define DECLARE_SET_METHOD(Class, T, __set__) \
BEGIN_DECLARE_METHOD(Class, __set__) { \
self->__set__(qscriptvalue_cast<T>(ctx->argument(0))); \
return eng->undefinedValue(); \
} END_DECLARE_METHOD
#define DECLARE_GET_SET_METHODS(Class, T, __get__, __set__) \
DECLARE_GET_METHOD(Class, /*T,*/ __get__) \
DECLARE_SET_METHOD(Class, T, __set__)
#define DECLARE_SIMPLE_GET_METHOD(Class, __get__) \
BEGIN_DECLARE_METHOD(Class, __get__) { \
return QScriptValue(eng, self->__get__()); \
} END_DECLARE_METHOD
#define DECLARE_SIMPLE_SET_METHOD(Class, ToType, __set__) \
BEGIN_DECLARE_METHOD(Class, __set__) { \
self->__set__(ctx->argument(0).ToType()); \
return eng->undefinedValue(); \
} END_DECLARE_METHOD
#define DECLARE_BOOLEAN_GET_METHOD(Class, __set__) \
DECLARE_SIMPLE_GET_METHOD(Class, __set__)
#define DECLARE_BOOLEAN_SET_METHOD(Class, __set__) \
DECLARE_SIMPLE_SET_METHOD(Class, toBoolean, __set__)
#define DECLARE_INT_GET_METHOD(Class, __set__) \
DECLARE_SIMPLE_GET_METHOD(Class, __set__)
#define DECLARE_INT_SET_METHOD(Class, __set__) \
DECLARE_SIMPLE_SET_METHOD(Class, toInt32, __set__)
#define DECLARE_NUMBER_GET_METHOD(Class, __set__) \
DECLARE_SIMPLE_GET_METHOD(Class, __set__)
#define DECLARE_NUMBER_SET_METHOD(Class, __set__) \
DECLARE_SIMPLE_SET_METHOD(Class, toNumber, __set__)
#define DECLARE_STRING_GET_METHOD(Class, __set__) \
DECLARE_SIMPLE_GET_METHOD(Class, __set__)
#define DECLARE_STRING_SET_METHOD(Class, __set__) \
DECLARE_SIMPLE_SET_METHOD(Class, toString, __set__)
#define DECLARE_QOBJECT_GET_METHOD(Class, __get__) \
BEGIN_DECLARE_METHOD(Class, __get__) { \
return eng->newQObject(self->__get__()); \
} END_DECLARE_METHOD
#define DECLARE_QOBJECT_SET_METHOD(Class, __set__) \
DECLARE_SIMPLE_SET_METHOD(Class, toQObject, __set__)
#define DECLARE_BOOLEAN_GET_SET_METHODS(Class, __get__, __set__) \
DECLARE_BOOLEAN_GET_METHOD(Class, __get__) \
DECLARE_BOOLEAN_SET_METHOD(Class, __set__)
#define DECLARE_NUMBER_GET_SET_METHODS(Class, __get__, __set__) \
DECLARE_NUMBER_GET_METHOD(Class, __get__) \
DECLARE_NUMBER_SET_METHOD(Class, __set__)
#define DECLARE_INT_GET_SET_METHODS(Class, __get__, __set__) \
DECLARE_INT_GET_METHOD(Class, __get__) \
DECLARE_INT_SET_METHOD(Class, __set__)
#define DECLARE_STRING_GET_SET_METHODS(Class, __get__, __set__) \
DECLARE_STRING_GET_METHOD(Class, __get__) \
DECLARE_STRING_SET_METHOD(Class, __set__)
#define DECLARE_QOBJECT_GET_SET_METHODS(Class, __get__, __set__) \
DECLARE_QOBJECT_GET_METHOD(Class, __get__) \
DECLARE_QOBJECT_SET_METHOD(Class, __set__)
#define DECLARE_VOID_METHOD(Class, __fun__) \
BEGIN_DECLARE_METHOD(Class, __fun__) { \
self->__fun__(); \
return eng->undefinedValue(); \
} END_DECLARE_METHOD
#define DECLARE_VOID_NUMBER_METHOD(Class, __fun__) \
BEGIN_DECLARE_METHOD(Class, __fun__) { \
self->__fun__(ctx->argument(0).toNumber()); \
return eng->undefinedValue(); \
} END_DECLARE_METHOD
#define DECLARE_VOID_NUMBER_NUMBER_METHOD(Class, __fun__) \
BEGIN_DECLARE_METHOD(Class, __fun__) { \
self->__fun__(ctx->argument(0).toNumber(), ctx->argument(1).toNumber()); \
return eng->undefinedValue(); \
} END_DECLARE_METHOD
#define DECLARE_VOID_QUAD_NUMBER_METHOD(Class, __fun__) \
BEGIN_DECLARE_METHOD(Class, __fun__) { \
self->__fun__(ctx->argument(0).toNumber(), ctx->argument(1).toNumber(), ctx->argument(2).toNumber(), ctx->argument(3).toNumber()); \
return eng->undefinedValue(); \
} END_DECLARE_METHOD
#define DECLARE_VOID_1ARG_METHOD(Class, ArgType, __fun__) \
BEGIN_DECLARE_METHOD(Class, __fun__) { \
self->__fun__(qscriptvalue_cast<ArgType>(ctx->argument(0))); \
return eng->undefinedValue(); \
} END_DECLARE_METHOD
#define DECLARE_BOOLEAN_1ARG_METHOD(Class, ArgType, __fun__) \
BEGIN_DECLARE_METHOD(Class, __fun__) { \
return QScriptValue(eng, self->__fun__(qscriptvalue_cast<ArgType>(ctx->argument(0)))); \
} END_DECLARE_METHOD
#define DECLARE_POINTER_METATYPE(T) \
Q_DECLARE_METATYPE(T*) \
Q_DECLARE_METATYPE(QScript::Pointer<T>::wrapped_pointer_type)
namespace QScript
{
enum {
UserOwnership = 1
};
template <typename T>
class Pointer : public QSharedData
{
public:
typedef T* pointer_type;
typedef QExplicitlySharedDataPointer<Pointer<T> > wrapped_pointer_type;
~Pointer()
{
if (!(m_flags & UserOwnership))
delete m_value;
}
operator T*()
{
return m_value;
}
operator const T*() const
{
return m_value;
}
static wrapped_pointer_type create(T *value, uint flags = 0)
{
return wrapped_pointer_type(new Pointer(value, flags));
}
static QScriptValue toScriptValue(QScriptEngine *engine, T* const &source)
{
if (!source)
return engine->nullValue();
return engine->newVariant(qVariantFromValue(source));
}
static void fromScriptValue(const QScriptValue &value, T* &target)
{
if (value.isVariant()) {
QVariant var = value.toVariant();
if (qVariantCanConvert<T*>(var)) {
target = qvariant_cast<T*>(var);
} else if (qVariantCanConvert<wrapped_pointer_type>(var)) {
target = qvariant_cast<wrapped_pointer_type>(var)->operator T*();
} else {
// look in prototype chain
target = 0;
int type = qMetaTypeId<T*>();
int pointerType = qMetaTypeId<wrapped_pointer_type>();
QScriptValue proto = value.prototype();
while (proto.isObject() && proto.isVariant()) {
int protoType = proto.toVariant().userType();
if ((type == protoType) || (pointerType == protoType)) {
QByteArray name = QMetaType::typeName(var.userType());
if (name.startsWith("QScript::Pointer<")) {
target = (*reinterpret_cast<wrapped_pointer_type*>(var.data()))->operator T*();
break;
} else {
target = static_cast<T*>(var.data());
break;
}
}
proto = proto.prototype();
}
}
} else if (value.isQObject()) {
QObject *qobj = value.toQObject();
QByteArray typeName = QMetaType::typeName(qMetaTypeId<T*>());
target = reinterpret_cast<T*>(qobj->qt_metacast(typeName.left(typeName.size()-1)));
} else {
target = 0;
}
}
uint flags() const
{ return m_flags; }
void setFlags(uint flags)
{ m_flags = flags; }
void unsetFlags(uint flags)
{ m_flags &= ~flags; }
protected:
Pointer(T* value, uint flags)
: m_flags(flags), m_value(value)
{}
private:
uint m_flags;
T* m_value;
};
template <typename T>
int registerPointerMetaType(
QScriptEngine *eng,
const QScriptValue &prototype = QScriptValue(),
T * /* dummy */ = 0
)
{
QScriptValue (*mf)(QScriptEngine *, T* const &) = Pointer<T>::toScriptValue;
void (*df)(const QScriptValue &, T* &) = Pointer<T>::fromScriptValue;
const int id = qMetaTypeId<T*>();
qScriptRegisterMetaType_helper(
eng, id, reinterpret_cast<QScriptEngine::MarshalFunction>(mf),
reinterpret_cast<QScriptEngine::DemarshalFunction>(df),
prototype);
eng->setDefaultPrototype(qMetaTypeId<typename Pointer<T>::wrapped_pointer_type>(), prototype);
return id;
}
inline void maybeReleaseOwnership(const QScriptValue &value)
{
if (value.isVariant()) {
QVariant var = value.toVariant();
QByteArray name = QMetaType::typeName(var.userType());
if (name.startsWith("QScript::Pointer<"))
(*reinterpret_cast<Pointer<void*>::wrapped_pointer_type *>(var.data()))->setFlags(UserOwnership);
}
}
inline void maybeTakeOwnership(const QScriptValue &value)
{
if (value.isVariant()) {
QVariant var = value.toVariant();
QByteArray name = QMetaType::typeName(var.userType());
if (name.startsWith("QScript::Pointer<"))
(*reinterpret_cast<Pointer<void*>::wrapped_pointer_type *>(var.data()))->unsetFlags(UserOwnership);
}
}
template <class T>
inline QScriptValue wrapPointer(QScriptEngine *eng, T *ptr, uint flags = 0)
{
return eng->newVariant(qVariantFromValue(Pointer<T>::create(ptr, flags)));
}
} // namespace QScript
#endif // QTSCRIPTEXTENSIONS_GLOBAL_H

View File

@ -1,188 +0,0 @@
/*
* Copyright 2011-2012 by Sebastian Kügler <sebas@kde.org>
* Copyright 2013 by Aaron Seigo <aseigo@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 "configgroup.h"
#include <QtCore/QTimer>
#include <kconfig.h>
#include <kconfiggroup.h>
#include <ksharedconfig.h>
#include <QDebug>
class ConfigGroupPrivate {
public:
ConfigGroupPrivate(ConfigGroup *q)
: q(q),
config(0),
configGroup(0)
{}
~ConfigGroupPrivate()
{
delete configGroup;
}
ConfigGroup* q;
KSharedConfigPtr config;
KConfigGroup *configGroup;
QString file;
QTimer *synchTimer;
QString group;
};
ConfigGroup::ConfigGroup(QObject *parent)
: QObject(parent),
d(new ConfigGroupPrivate(this))
{
// Delay and compress everything within 5 seconds into one sync
d->synchTimer = new QTimer(this);
d->synchTimer->setSingleShot(true);
d->synchTimer->setInterval(1500);
connect(d->synchTimer, SIGNAL(timeout()), SLOT(sync()));
}
ConfigGroup::~ConfigGroup()
{
if (d->synchTimer->isActive()) {
//qDebug() << "SYNC......";
d->synchTimer->stop();
d->configGroup->sync();
}
delete d;
}
KConfigGroup* ConfigGroup::configGroup()
{
return d->configGroup;
}
QString ConfigGroup::file() const
{
return d->file;
}
void ConfigGroup::setFile(const QString& filename)
{
if (d->file == filename) {
return;
}
d->file = filename;
readConfigFile();
emit fileChanged();
}
QString ConfigGroup::group() const
{
return d->group;
}
void ConfigGroup::setGroup(const QString& groupname)
{
if (d->group == groupname) {
return;
}
d->group = groupname;
readConfigFile();
emit groupChanged();
emit keyListChanged();
}
QStringList ConfigGroup::keyList() const
{
if (!d->configGroup) {
return QStringList();
}
return d->configGroup->keyList();
}
QStringList ConfigGroup::groupList() const
{
return d->configGroup->groupList();
}
bool ConfigGroup::readConfigFile()
{
// Find parent ConfigGroup
ConfigGroup* parentGroup = 0;
QObject* current = parent();
while (current) {
parentGroup = qobject_cast<ConfigGroup*>(current);
if (parentGroup) {
break;
}
current = current->parent();
}
delete d->configGroup;
d->configGroup = 0;
if (parentGroup) {
d->configGroup = new KConfigGroup(parentGroup->configGroup(), d->group);
return true;
} else {
if (d->file.isEmpty()) {
qWarning() << "Could not find KConfig Parent: specify a file or parent to another ConfigGroup";
return false;
}
d->config = KSharedConfig::openConfig(d->file);
d->configGroup = new KConfigGroup(d->config, d->group);
return true;
}
}
// Bound methods and slots
bool ConfigGroup::writeEntry(const QString& key, const QVariant& value)
{
if (!d->configGroup) {
return false;
}
d->configGroup->writeEntry(key, value);
d->synchTimer->start();
return true;
}
QVariant ConfigGroup::readEntry(const QString& key)
{
if (!d->configGroup) {
return QVariant();
}
const QVariant value = d->configGroup->readEntry(key, QVariant(""));
//qDebug() << " reading setting: " << key << value;
return value;
}
void ConfigGroup::deleteEntry(const QString& key)
{
d->configGroup->deleteEntry(key);
}
void ConfigGroup::sync()
{
if (d->configGroup) {
//qDebug() << "synching config...";
d->configGroup->sync();
}
}
#include "configgroup.moc"

View File

@ -1,69 +0,0 @@
/*
* Copyright 2011-2012 by Sebastian Kügler <sebas@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 CONFIGGROUP_H
#define CONFIGGROUP_H
#include <QObject>
#include <QVariant>
class KConfigGroup;
class ConfigGroupPrivate;
class ConfigGroup : public QObject
{
Q_OBJECT
Q_PROPERTY(QString file READ file WRITE setFile NOTIFY fileChanged)
Q_PROPERTY(QString group READ group WRITE setGroup NOTIFY groupChanged)
Q_PROPERTY(QStringList keyList READ keyList NOTIFY keyListChanged)
Q_PROPERTY(QStringList groupList READ groupList NOTIFY groupListChanged)
public:
ConfigGroup(QObject* parent=0);
~ConfigGroup();
KConfigGroup* configGroup();
QString file() const;
void setFile(const QString &filename);
QString group() const;
void setGroup(const QString &groupname);
QStringList keyList() const;
QStringList groupList() const;
Q_INVOKABLE QVariant readEntry(const QString &key);
Q_INVOKABLE bool writeEntry(const QString &key, const QVariant &value);
Q_INVOKABLE void deleteEntry(const QString& key);
Q_SIGNALS:
void fileChanged();
void groupChanged();
void keyListChanged();
void groupListChanged();
private:
ConfigGroupPrivate* d;
bool readConfigFile();
private Q_SLOTS:
void sync();
};
#endif

View File

@ -1,290 +0,0 @@
/*
* Copyright 2009 Aaron Seigo <aseigo@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 "containment.h"
#include <QAction>
#include <klocalizedstring.h>
#include <kactioncollection.h>
#include <Plasma/Corona>
#include <Plasma/Containment>
#include "scriptengine.h"
#include "widget.h"
namespace WorkspaceScripting
{
class Containment::Private
{
public:
QWeakPointer<Plasma::Containment> containment;
QString oldWallpaperPlugin;
QString wallpaperPlugin;
QString oldWallpaperMode;
QString wallpaperMode;
};
Containment::Containment(Plasma::Containment *containment, QObject *parent)
: Applet(parent),
d(new Containment::Private)
{
d->containment = containment;
setCurrentConfigGroup(QStringList());
setCurrentGlobalConfigGroup(QStringList());
if (containment) {
d->oldWallpaperPlugin = d->wallpaperPlugin = containment->wallpaper();
}
}
Containment::~Containment()
{
if (d->containment) {
Plasma::Containment *containment = d->containment.data();
if (d->oldWallpaperPlugin != d->wallpaperPlugin ||
d->oldWallpaperMode != d->wallpaperMode) {
containment->setWallpaper(d->wallpaperPlugin);
} else if (wallpaperConfigDirty()) {
KConfigGroup cg(containment->config());
cg = KConfigGroup(&cg, "Wallpaper");
cg = KConfigGroup(&cg, containment->wallpaper());
}
}
reloadConfigIfNeeded();
delete d;
}
int Containment::screen() const
{
if (!d->containment) {
return -1;
}
return d->containment.data()->screen();
}
QString Containment::wallpaperPlugin() const
{
return d->wallpaperPlugin;
}
void Containment::setWallpaperPlugin(const QString &wallpaperPlugin)
{
d->wallpaperPlugin = wallpaperPlugin;
}
QString Containment::wallpaperMode() const
{
return d->wallpaperMode;
}
void Containment::setWallpaperMode(const QString &wallpaperMode)
{
d->wallpaperMode = wallpaperMode;
}
QString Containment::formFactor() const
{
if (!d->containment) {
return "Planar";
}
switch (d->containment.data()->formFactor()) {
case Plasma::Types::Planar:
return "planar";
break;
case Plasma::Types::MediaCenter:
return "mediacenter";
break;
case Plasma::Types::Horizontal:
return "horizontal";
break;
case Plasma::Types::Vertical:
return "vertical";
break;
case Plasma::Types::Application:
return "application";
break;
}
return "Planar";
}
QList<int> Containment::widgetIds() const
{
//FIXME: the ints could overflow since Applet::id() returns a uint,
// however QScript deals with QList<uint> very, very poory
QList<int> w;
if (d->containment) {
foreach (const Plasma::Applet *applet, d->containment.data()->applets()) {
w.append(applet->id());
}
}
return w;
}
QScriptValue Containment::widgetById(QScriptContext *context, QScriptEngine *engine)
{
if (context->argumentCount() == 0) {
return context->throwError(i18n("widgetById requires an id"));
}
const uint id = context->argument(0).toInt32();
Containment *c = qobject_cast<Containment*>(context->thisObject().toQObject());
if (!c) {
return engine->undefinedValue();
}
if (c->d->containment) {
foreach (Plasma::Applet *w, c->d->containment.data()->applets()) {
if (w->id() == id) {
ScriptEngine *env = ScriptEngine::envFor(engine);
return env->wrap(w);
}
}
}
return engine->undefinedValue();
}
QScriptValue Containment::addWidget(QScriptContext *context, QScriptEngine *engine)
{
if (context->argumentCount() == 0) {
return context->throwError(i18n("widgetById requires a name of a widget or a widget object"));
}
Containment *c = qobject_cast<Containment*>(context->thisObject().toQObject());
if (!c || !c->d->containment) {
return engine->undefinedValue();
}
QScriptValue v = context->argument(0);
Plasma::Applet *applet = 0;
if (v.isString()) {
applet = c->d->containment.data()->createApplet(v.toString());
if (applet) {
ScriptEngine *env = ScriptEngine::envFor(engine);
return env->wrap(applet);
}
} else if (Widget *widget = qobject_cast<Widget*>(v.toQObject())) {
applet = widget->applet();
c->d->containment.data()->addApplet(applet);
return v;
}
return engine->undefinedValue();
}
QScriptValue Containment::widgets(QScriptContext *context, QScriptEngine *engine)
{
Containment *c = qobject_cast<Containment*>(context->thisObject().toQObject());
if (!c || !c->d->containment) {
return engine->undefinedValue();
}
const QString widgetType = context->argumentCount() > 0 ? context->argument(0).toString() : QString();
QScriptValue widgets = engine->newArray();
ScriptEngine *env = ScriptEngine::envFor(engine);
int count = 0;
foreach (Plasma::Applet *widget, c->d->containment.data()->applets()) {
if (widgetType.isEmpty() || widget->pluginInfo().pluginName() == widgetType) {
widgets.setProperty(count, env->wrap(widget));
++count;
}
}
widgets.setProperty("length", count);
return widgets;
}
uint Containment::id() const
{
if (!d->containment) {
return 0;
}
return d->containment.data()->id();
}
QString Containment::name() const
{
if (!d->containment) {
return QString();
}
return d->containment.data()->activity();
}
void Containment::setName(const QString &name)
{
if (d->containment) {
d->containment.data()->setActivity(name);
}
}
QString Containment::type() const
{
if (!d->containment) {
return QString();
}
return d->containment.data()->pluginInfo().pluginName();
}
void Containment::remove()
{
if (d->containment) {
d->containment.data()->destroy();
}
}
void Containment::showConfigurationInterface()
{
if (d->containment) {
QAction *configAction = d->containment.data()->actions()->action("configure");
if (configAction && configAction->isEnabled()) {
configAction->trigger();
}
}
}
Plasma::Applet *Containment::applet() const
{
return d->containment.data();
}
Plasma::Containment *Containment::containment() const
{
return d->containment.data();
}
}
#include "containment.moc"

View File

@ -1,104 +0,0 @@
/*
* Copyright 2009 Aaron Seigo <aseigo@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 CONTAINMENT
#define CONTAINMENT
#include <QScriptContext>
#include <QScriptValue>
#include <QWeakPointer>
#include "applet.h"
namespace Plasma
{
class Containment;
} // namespace Plasma
namespace WorkspaceScripting
{
class Containment : public Applet
{
Q_OBJECT
///FIXME: add NOTIFY
Q_PROPERTY(QString version READ version)
Q_PROPERTY(QStringList configKeys READ configKeys)
Q_PROPERTY(QStringList configGroups READ configGroups)
Q_PROPERTY(QStringList globalConfigKeys READ globalConfigKeys)
Q_PROPERTY(QStringList globalConfigGroups READ globalConfigGroups)
Q_PROPERTY(QStringList currentConfigGroup WRITE setCurrentConfigGroup READ currentConfigGroup)
Q_PROPERTY(QString name READ name WRITE setName)
Q_PROPERTY(QString wallpaperPlugin READ wallpaperPlugin WRITE setWallpaperPlugin)
Q_PROPERTY(QString wallpaperMode READ wallpaperMode WRITE setWallpaperMode)
Q_PROPERTY(bool locked READ locked WRITE setLocked)
Q_PROPERTY(QString type READ type)
Q_PROPERTY(QString formFactor READ formFactor)
Q_PROPERTY(QList<int> widgetIds READ widgetIds)
Q_PROPERTY(int screen READ screen)
Q_PROPERTY(int id READ id)
public:
Containment(Plasma::Containment *containment, QObject *parent = 0);
~Containment();
uint id() const;
QString type() const;
QString formFactor() const;
QList<int> widgetIds() const;
QString name() const;
void setName(const QString &name);
int screen() const;
Plasma::Applet *applet() const;
Plasma::Containment *containment() const;
QString wallpaperPlugin() const;
void setWallpaperPlugin(const QString &wallpaperPlugin);
QString wallpaperMode() const;
void setWallpaperMode(const QString &wallpaperMode);
static QScriptValue widgetById(QScriptContext *context, QScriptEngine *engine);
static QScriptValue addWidget(QScriptContext *context, QScriptEngine *engine);
static QScriptValue widgets(QScriptContext *context, QScriptEngine *engine);
public Q_SLOTS:
void remove();
void showConfigurationInterface();
// from the applet interface
QVariant readConfig(const QString &key, const QVariant &def = QString()) const { return Applet::readConfig(key, def); }
void writeConfig(const QString &key, const QVariant &value) { Applet::writeConfig(key, value); }
QVariant readGlobalConfig(const QString &key, const QVariant &def = QString()) const { return Applet::readGlobalConfig(key, def); }
void writeGlobalConfig(const QString &key, const QVariant &value) { Applet::writeGlobalConfig(key, value); }
void reloadConfig() { Applet::reloadConfig(); }
private:
class Private;
Private * const d;
};
}
#endif

View File

@ -1,63 +0,0 @@
/*
* Copyright 2010 Aaron Seigo <aseigo@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 "desktopscriptengine.h"
#include <QApplication>
#include <QCursor>
#include <QDesktopWidget>
#include "containment.h"
#include "appinterface.h"
#include "panel.h"
namespace WorkspaceScripting
{
DesktopScriptEngine::DesktopScriptEngine(ShellCorona *corona, bool startup, QObject *parent)
: ScriptEngine(corona, parent),
m_startup(startup)
{
}
QScriptValue DesktopScriptEngine::wrap(Plasma::Containment *c)
{
Containment *wrapper = isPanel(c) ? new Panel(c) : new Containment(c);
return wrap(wrapper);
}
QScriptValue DesktopScriptEngine::wrap(Containment *c)
{
return ScriptEngine::wrap(c);
}
int DesktopScriptEngine::defaultPanelScreen() const
{
if (m_startup) {
return ScriptEngine::defaultPanelScreen();
} else {
return qApp->desktop()->screenNumber(QCursor::pos());
}
}
}
#include "desktopscriptengine.moc"

View File

@ -1,47 +0,0 @@
/*
* Copyright 2010 Aaron Seigo <aseigo@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 DESKTOPSCRIPTENGINE
#define DESKTOPSCRIPTENGINE
#include "scriptengine.h"
class ShellCorona;
namespace WorkspaceScripting
{
class DesktopScriptEngine : public ScriptEngine
{
Q_OBJECT
public:
DesktopScriptEngine(ShellCorona *corona, bool isStartup = true, QObject *parent = 0);
QScriptValue wrap(Plasma::Containment *c);
QScriptValue wrap(Containment *c);
int defaultPanelScreen() const;
private:
bool m_startup;
};
}
#endif

View File

@ -1,121 +0,0 @@
/*
* Copyright 2009 Aaron Seigo <aseigo@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 "i18n.h"
#include <QScriptContext>
#include <QScriptEngine>
#include <QDebug>
#include <klocalizedstring.h>
QScriptValue jsi18n(QScriptContext *context, QScriptEngine *engine)
{
Q_UNUSED(engine)
if (context->argumentCount() < 1) {
// qDebug() << i18n("i18n() takes at least one argument");
return engine->undefinedValue();
}
KLocalizedString message = ki18n(context->argument(0).toString().toUtf8());
const int numArgs = context->argumentCount();
for (int i = 1; i < numArgs; ++i) {
message = message.subs(context->argument(i).toString());
}
return message.toString();
}
QScriptValue jsi18nc(QScriptContext *context, QScriptEngine *engine)
{
Q_UNUSED(engine)
if (context->argumentCount() < 2) {
// qDebug() << i18n("i18nc() takes at least two arguments");
return engine->undefinedValue();
}
KLocalizedString message = ki18nc(context->argument(0).toString().toUtf8(),
context->argument(1).toString().toUtf8());
const int numArgs = context->argumentCount();
for (int i = 2; i < numArgs; ++i) {
message = message.subs(context->argument(i).toString());
}
return message.toString();
}
QScriptValue jsi18np(QScriptContext *context, QScriptEngine *engine)
{
Q_UNUSED(engine)
if (context->argumentCount() < 2) {
// qDebug() << i18n("i18np() takes at least two arguments");
return engine->undefinedValue();
}
KLocalizedString message = ki18np(context->argument(0).toString().toUtf8(),
context->argument(1).toString().toUtf8());
const int numArgs = context->argumentCount();
for (int i = 2; i < numArgs; ++i) {
QScriptValue v = context->argument(i);
if (v.isNumber()) {
message = message.subs(v.toInt32());
} else {
message = message.subs(v.toString());
}
}
return message.toString();
}
QScriptValue jsi18ncp(QScriptContext *context, QScriptEngine *engine)
{
Q_UNUSED(engine)
if (context->argumentCount() < 3) {
// qDebug() << i18n("i18ncp() takes at least three arguments");
return engine->undefinedValue();
}
KLocalizedString message = ki18ncp(context->argument(0).toString().toUtf8(),
context->argument(1).toString().toUtf8(),
context->argument(2).toString().toUtf8());
const int numArgs = context->argumentCount();
for (int i = 3; i < numArgs; ++i) {
message = message.subs(context->argument(i).toString());
}
return message.toString();
}
void bindI18N(QScriptEngine *engine)
{
QScriptValue global = engine->globalObject();
global.setProperty("i18n", engine->newFunction(jsi18n));
global.setProperty("i18nc", engine->newFunction(jsi18nc));
global.setProperty("i18np", engine->newFunction(jsi18np));
global.setProperty("i18ncp", engine->newFunction(jsi18ncp));
}

View File

@ -1,35 +0,0 @@
/*
* Copyright 2009 Aaron Seigo <aseigo@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 JAVASCRIPTBINDI18N_H
#define JAVASCRIPTBINDI18N_H
#include <QScriptValue>
class QScriptContext;
class QScriptEngine;
QScriptValue jsi18n(QScriptContext *context, QScriptEngine *engine);
QScriptValue jsi18nc(QScriptContext *context, QScriptEngine *engine);
QScriptValue jsi18np(QScriptContext *context, QScriptEngine *engine);
QScriptValue jsi18ncp(QScriptContext *context, QScriptEngine *engine);
void bindI18N(QScriptEngine *engine);
#endif

View File

@ -1,367 +0,0 @@
/*
* Copyright 2009 Aaron Seigo <aseigo@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 "panel.h"
#include <QAction>
#include <QQuickItem>
#include <Plasma/Corona>
#include <Plasma/Containment>
#include <QScreen>
#include "shellcorona.h"
#include "panelview.h"
#include "scriptengine.h"
#include "widget.h"
namespace WorkspaceScripting
{
Panel::Panel(Plasma::Containment *containment, QObject *parent)
: Containment(containment, parent)
{
m_corona = qobject_cast<ShellCorona *>(containment->corona());
}
Panel::~Panel()
{
}
QString Panel::location() const
{
Plasma::Containment *c = containment();
if (!c) {
return "floating";
}
switch (c->location()) {
case Plasma::Types::Floating:
return "floating";
break;
case Plasma::Types::Desktop:
return "desktop";
break;
case Plasma::Types::FullScreen:
return "fullscreen";
break;
case Plasma::Types::TopEdge:
return "top";
break;
case Plasma::Types::BottomEdge:
return "bottom";
break;
case Plasma::Types::LeftEdge:
return "left";
break;
case Plasma::Types::RightEdge:
return "right";
break;
}
return "floating";
}
void Panel::setLocation(const QString &locationString)
{
Plasma::Containment *c = containment();
if (!c) {
return;
}
const QString lower = locationString.toLower();
Plasma::Types::Location loc = Plasma::Types::Floating;
Plasma::Types::FormFactor ff = Plasma::Types::Planar;
if (lower == "desktop") {
loc = Plasma::Types::Desktop;
} else if (lower == "fullscreen") {
loc = Plasma::Types::FullScreen;
} else if (lower == "top") {
loc = Plasma::Types::TopEdge;
ff = Plasma::Types::Horizontal;
} else if (lower == "bottom") {
loc = Plasma::Types::BottomEdge;
ff = Plasma::Types::Horizontal;
} else if (lower == "left") {
loc = Plasma::Types::LeftEdge;
ff = Plasma::Types::Vertical;
} else if (lower == "right") {
loc = Plasma::Types::RightEdge;
ff = Plasma::Types::Vertical;
}
c->setLocation(loc);
c->setFormFactor(ff);
}
PanelView *Panel::panel() const
{
Plasma::Containment *c = containment();
if (!c) {
return 0;
}
return m_corona->panelView(c);
}
QString Panel::alignment() const
{
PanelView *v = panel();
if (!v) {
return "left";
}
switch (v->alignment()) {
case Qt::AlignRight:
return "right";
break;
case Qt::AlignCenter:
return "center";
break;
default:
return "left";
break;
}
return "left";
}
void Panel::setAlignment(const QString &alignment)
{
PanelView *v = panel();
if (v) {
bool success = false;
if (alignment.compare("left", Qt::CaseInsensitive) == 0) {
success = true;
v->setAlignment(Qt::AlignLeft);
} else if (alignment.compare("right", Qt::CaseInsensitive) == 0) {
success = true;
v->setAlignment(Qt::AlignRight);
} else if (alignment.compare("center", Qt::CaseInsensitive) == 0) {
success = true;
v->setAlignment(Qt::AlignCenter);
}
if (success) {
v->setOffset(0);
}
}
}
int Panel::offset() const
{
PanelView *v = panel();
if (v) {
return v->offset();
}
return 0;
}
void Panel::setOffset(int pixels)
{
Plasma::Containment *c = containment();
if (pixels < 0 || !c) {
return;
}
QQuickItem *graphicObject = qobject_cast<QQuickItem *>(c->property("_plasma_graphicObject").value<QObject *>());
if (!graphicObject) {
return;
}
PanelView *v = panel();
if (v) {
QRectF screen = v->screen()->geometry();
QSizeF size(graphicObject->width(), graphicObject->height());
if (c->formFactor() == Plasma::Types::Vertical) {
if (pixels > screen.height()) {
return;
}
if (size.height() + pixels > screen.height()) {
graphicObject->setWidth(size.width());
graphicObject->setHeight(screen.height() - pixels);
}
} else if (pixels > screen.width()) {
return;
} else if (size.width() + pixels > screen.width()) {
size.setWidth(screen.width() - pixels);
graphicObject->setWidth(size.width());
graphicObject->setHeight(size.height());
v->setMinimumSize(size.toSize());
v->setMaximumSize(size.toSize());
}
v->setOffset(pixels);
}
}
int Panel::length() const
{
Plasma::Containment *c = containment();
if (!c) {
return 0;
}
QQuickItem *graphicObject = qobject_cast<QQuickItem *>(c->property("_plasma_graphicObject").value<QObject *>());
if (!graphicObject) {
return 0;
}
if (c->formFactor() == Plasma::Types::Vertical) {
return graphicObject->height();
} else {
return graphicObject->width();
}
}
void Panel::setLength(int pixels)
{
Plasma::Containment *c = containment();
if (pixels < 0 || !c) {
return;
}
QQuickItem *graphicObject = qobject_cast<QQuickItem *>(c->property("_plasma_graphicObject").value<QObject *>());
if (!graphicObject) {
return;
}
PanelView *v = panel();
if (v) {
QRectF screen = v->screen()->geometry();
QSizeF s(graphicObject->width(), graphicObject->height());
if (c->formFactor() == Plasma::Types::Vertical) {
if (pixels > screen.height() - v->offset()) {
return;
}
s.setHeight(pixels);
} else if (pixels > screen.width() - v->offset()) {
return;
} else {
s.setWidth(pixels);
}
graphicObject->setWidth(s.width());
graphicObject->setHeight(s.height());
v->setMinimumSize(s.toSize());
v->setMaximumSize(s.toSize());
}
}
int Panel::height() const
{
Plasma::Containment *c = containment();
if (!c) {
return 0;
}
QQuickItem *graphicObject = qobject_cast<QQuickItem *>(c->property("_plasma_graphicObject").value<QObject *>());
if (!graphicObject) {
return 0;
}
return c->formFactor() == Plasma::Types::Vertical ? graphicObject->width()
: graphicObject->height();
}
void Panel::setHeight(int height)
{
Plasma::Containment *c = containment();
if (height < 16 || !c) {
return;
}
QQuickItem *graphicObject = qobject_cast<QQuickItem *>(c->property("_plasma_graphicObject").value<QObject *>());
if (!graphicObject) {
return;
}
PanelView *v = panel();
if (v) {
QRect screen = v->screen()->geometry();
QSizeF size(graphicObject->width(), graphicObject->height());
const int max = (c->formFactor() == Plasma::Types::Vertical ? screen.width() : screen.height()) / 3;
height = qBound(16, height, max);
if (c->formFactor() == Plasma::Types::Vertical) {
size.setWidth(height);
} else {
size.setHeight(height);
}
graphicObject->setWidth(size.width());
graphicObject->setHeight(size.height());
v->setMinimumSize(size.toSize());
v->setMaximumSize(size.toSize());
}
}
QString Panel::hiding() const
{
/*PanelView *v = panel();
if (v) {
switch (v->visibilityMode()) {
case PanelView::NormalPanel:
return "none";
break;
case PanelView::AutoHide:
return "autohide";
break;
case PanelView::LetWindowsCover:
return "windowscover";
break;
case PanelView::WindowsGoBelow:
return "windowsbelow";
break;
}
}*/
return "none";
}
void Panel::setHiding(const QString &mode)
{
/*PanelView *v = panel();
if (v) {
if (mode.compare("autohide", Qt::CaseInsensitive) == 0) {
v->setVisibilityMode(PanelView::AutoHide);
} else if (mode.compare("windowscover", Qt::CaseInsensitive) == 0) {
v->setVisibilityMode(PanelView::LetWindowsCover);
} else if (mode.compare("windowsbelow", Qt::CaseInsensitive) == 0) {
v->setVisibilityMode(PanelView::WindowsGoBelow);
} else {
v->setVisibilityMode(PanelView::NormalPanel);
}
}*/
}
}
#include "panel.moc"

View File

@ -1,97 +0,0 @@
/*
* Copyright 2009 Aaron Seigo <aseigo@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 PANEL
#define PANEL
#include <QScriptContext>
#include <QScriptValue>
#include <QWeakPointer>
#include "containment.h"
class PanelView;
class ShellCorona;
namespace WorkspaceScripting
{
class Panel : public Containment
{
Q_OBJECT
Q_PROPERTY(QStringList configKeys READ configKeys)
Q_PROPERTY(QStringList configGroups READ configGroups)
Q_PROPERTY(QStringList currentConfigGroup WRITE setCurrentConfigGroup READ currentConfigGroup)
Q_PROPERTY(QString name READ name WRITE setName)
Q_PROPERTY(QString version READ version)
Q_PROPERTY(QString type READ type)
Q_PROPERTY(QString formFactor READ formFactor)
Q_PROPERTY(QList<int> widgetIds READ widgetIds)
Q_PROPERTY(int screen READ screen)
Q_PROPERTY(QString location READ location WRITE setLocation)
Q_PROPERTY(int id READ id)
// panel properties
Q_PROPERTY(QString alignment READ alignment WRITE setAlignment)
Q_PROPERTY(int offset READ offset WRITE setOffset)
Q_PROPERTY(int length READ length WRITE setLength)
Q_PROPERTY(int height READ height WRITE setHeight)
Q_PROPERTY(QString hiding READ hiding WRITE setHiding)
public:
Panel(Plasma::Containment *containment, QObject *parent = 0);
~Panel();
QString location() const;
void setLocation(const QString &location);
QString alignment() const;
void setAlignment(const QString &alignment);
int offset() const;
void setOffset(int pixels);
int length() const;
void setLength(int pixels);
int height() const;
void setHeight(int height);
QString hiding() const;
void setHiding(const QString &mode);
public Q_SLOTS:
void remove() { Containment::remove(); }
void showConfigurationInterface() { Containment::showConfigurationInterface(); }
// from the applet interface
QVariant readConfig(const QString &key, const QVariant &def = QString()) const { return Applet::readConfig(key, def); }
void writeConfig(const QString &key, const QVariant &value) { Applet::writeConfig(key, value); }
void reloadConfig() { Applet::reloadConfig(); }
private:
PanelView *panel() const;
ShellCorona *m_corona;
};
}
#endif

View File

@ -1,330 +0,0 @@
/*
* Copyright 2007 Richard J. Moore <rich@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* 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 Library 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 <QtScript/QScriptValue>
#include <QtScript/QScriptEngine>
#include <QtScript/QScriptContext>
#include <QtCore/QRectF>
#include "backportglobal.h"
Q_DECLARE_METATYPE(QRectF*)
Q_DECLARE_METATYPE(QRectF)
static QScriptValue ctor(QScriptContext *ctx, QScriptEngine *eng)
{
if (ctx->argumentCount() == 4)
{
qreal x = ctx->argument(0).toNumber();
qreal y = ctx->argument(1).toNumber();
qreal width = ctx->argument(2).toNumber();
qreal height = ctx->argument(3).toNumber();
return qScriptValueFromValue(eng, QRectF(x, y, width, height));
}
return qScriptValueFromValue(eng, QRectF());
}
static QScriptValue adjust(QScriptContext *ctx, QScriptEngine *)
{
DECLARE_SELF(QRectF, adjust);
qreal dx1 = ctx->argument(0).toNumber();
qreal dy1 = ctx->argument(1).toNumber();
qreal dx2 = ctx->argument(2).toNumber();
qreal dy2 = ctx->argument(3).toNumber();
self->adjust(dx1, dy1, dx2, dy2);
return QScriptValue();
}
static QScriptValue adjusted(QScriptContext *ctx, QScriptEngine *eng)
{
DECLARE_SELF(QRectF, adjusted);
qreal dx1 = ctx->argument(0).toNumber();
qreal dy1 = ctx->argument(1).toNumber();
qreal dx2 = ctx->argument(2).toNumber();
qreal dy2 = ctx->argument(3).toNumber();
QRectF tmp = self->adjusted(dx1, dy1, dx2, dy2);
return qScriptValueFromValue(eng, tmp);
}
static QScriptValue bottom(QScriptContext *ctx, QScriptEngine *eng)
{
DECLARE_SELF(QRectF, bottom);
if (ctx->argumentCount() > 0) {
int bottom = ctx->argument(0).toInt32();
self->setBottom(bottom);
}
return QScriptValue(eng, self->bottom());
}
static QScriptValue top(QScriptContext *ctx, QScriptEngine *eng)
{
DECLARE_SELF(QRectF, top);
if (ctx->argumentCount() > 0) {
int top = ctx->argument(0).toInt32();
self->setTop(top);
}
return QScriptValue(eng, self->top());
}
static QScriptValue contains(QScriptContext *ctx, QScriptEngine *eng)
{
DECLARE_SELF(QRectF, contains);
qreal x = ctx->argument(0).toNumber();
qreal y = ctx->argument(1).toNumber();
return QScriptValue(eng, self->contains(x, y));
}
static QScriptValue height(QScriptContext *ctx, QScriptEngine *eng)
{
DECLARE_SELF(QRectF, height);
if (ctx->argumentCount() > 0) {
int height = ctx->argument(0).toInt32();
self->setHeight(height);
}
return QScriptValue(eng, self->height());
}
static QScriptValue empty(QScriptContext *ctx, QScriptEngine *eng)
{
DECLARE_SELF(QRectF, empty);
return QScriptValue(eng, self->isEmpty());
}
static QScriptValue null(QScriptContext *ctx, QScriptEngine *eng)
{
DECLARE_SELF(QRectF, null);
return QScriptValue(eng, self->isNull());
}
static QScriptValue valid(QScriptContext *ctx, QScriptEngine *eng)
{
DECLARE_SELF(QRectF, valid);
return QScriptValue(eng, self->isValid());
}
static QScriptValue left(QScriptContext *ctx, QScriptEngine *eng)
{
DECLARE_SELF(QRectF, left);
if (ctx->argumentCount() > 0) {
int left = ctx->argument(0).toInt32();
self->setLeft(left);
}
return QScriptValue(eng, self->left());
}
static QScriptValue moveBottom(QScriptContext *ctx, QScriptEngine *)
{
DECLARE_SELF(QRectF, moveBottom);
qreal bottom = ctx->argument(0).toNumber();
self->moveBottom(bottom);
return QScriptValue();
}
static QScriptValue moveLeft(QScriptContext *ctx, QScriptEngine *)
{
DECLARE_SELF(QRectF, moveLeft);
qreal left = ctx->argument(0).toNumber();
self->moveBottom(left);
return QScriptValue();
}
static QScriptValue moveRight(QScriptContext *ctx, QScriptEngine *)
{
DECLARE_SELF(QRectF, moveRight);
qreal right = ctx->argument(0).toNumber();
self->moveBottom(right);
return QScriptValue();
}
static QScriptValue moveTo(QScriptContext *ctx, QScriptEngine *)
{
DECLARE_SELF(QRectF, moveTo);
qreal x = ctx->argument(0).toNumber();
qreal y = ctx->argument(1).toNumber();
self->moveTo(x, y);
return QScriptValue();
}
static QScriptValue moveTop(QScriptContext *ctx, QScriptEngine *)
{
DECLARE_SELF(QRectF, moveTop);
qreal top = ctx->argument(0).toNumber();
self->moveTop(top);
return QScriptValue();
}
static QScriptValue right(QScriptContext *ctx, QScriptEngine *eng)
{
DECLARE_SELF(QRectF, right);
if (ctx->argumentCount() > 0) {
int right = ctx->argument(0).toInt32();
self->setRight(right);
}
return QScriptValue(eng, self->right());
}
static QScriptValue setCoords(QScriptContext *ctx, QScriptEngine *)
{
DECLARE_SELF(QRectF, setCoords);
qreal x1 = ctx->argument(0).toNumber();
qreal y1 = ctx->argument(1).toNumber();
qreal x2 = ctx->argument(2).toNumber();
qreal y2 = ctx->argument(3).toNumber();
self->setCoords(x1, y1, x2, y2);
return QScriptValue();
}
static QScriptValue setRect(QScriptContext *ctx, QScriptEngine *)
{
DECLARE_SELF(QRectF, setRect);
qreal x = ctx->argument(0).toNumber();
qreal y = ctx->argument(1).toNumber();
qreal width = ctx->argument(2).toNumber();
qreal height = ctx->argument(3).toNumber();
self->setRect(x, y, width, height);
return QScriptValue();
}
static QScriptValue translate(QScriptContext *ctx, QScriptEngine *)
{
DECLARE_SELF(QRectF, translate);
qreal dx = ctx->argument(0).toNumber();
qreal dy = ctx->argument(1).toNumber();
self->translate(dx, dy);
return QScriptValue();
}
static QScriptValue width(QScriptContext *ctx, QScriptEngine *eng)
{
DECLARE_SELF(QRectF, width);
if (ctx->argumentCount() > 0) {
int width = ctx->argument(0).toInt32();
self->setWidth(width);
}
return QScriptValue(eng, self->width());
}
static QScriptValue x(QScriptContext *ctx, QScriptEngine *eng)
{
DECLARE_SELF(QRectF, x);
if (ctx->argumentCount() > 0) {
int x = ctx->argument(0).toInt32();
self->setX(x);
}
return QScriptValue(eng, self->x());
}
static QScriptValue y(QScriptContext *ctx, QScriptEngine *eng)
{
DECLARE_SELF(QRectF, y);
if (ctx->argumentCount() > 0) {
int y = ctx->argument(0).toInt32();
self->setY(y);
}
return QScriptValue(eng, self->y());
}
/* Not Implemented Yet */
// QPointF bottomLeft () const
// QPointF bottomRight () const
// QPointF center () const
// bool contains ( const QPointF & point ) const
// bool contains ( const QRectF & rectangle ) const
// void getCoords ( qreal * x1, qreal * y1, qreal * x2, qreal * y2 ) const
// void getRect ( qreal * x, qreal * y, qreal * width, qreal * height ) const
// QRectF intersected ( const QRectF & rectangle ) const
// bool intersects ( const QRectF & rectangle ) const
// void moveBottomLeft ( const QPointF & position )
// void moveBottomRight ( const QPointF & position )
// void moveCenter ( const QPointF & position )
// void moveTo ( const QPointF & position )
// void moveTopLeft ( const QPointF & position )
// void moveTopRight ( const QPointF & position )
// QRectF normalized () const
// void setBottomLeft ( const QPointF & position )
// void setBottomRight ( const QPointF & position )
// void setSize ( const QSizeF & size )
// void setTopLeft ( const QPointF & position )
// void setTopRight ( const QPointF & position )
// QSizeF size () const
// QRect toAlignedRect () const
// QRect toRect () const
// QPointF topLeft () const
// QPointF topRight () const
// void translate ( const QPointF & offset )
// QRectF translated ( qreal dx, qreal dy ) const
// QRectF translated ( const QPointF & offset ) const
// QRectF united ( const QRectF & rectangle ) const
QScriptValue constructQRectFClass(QScriptEngine *eng)
{
QScriptValue proto = qScriptValueFromValue(eng, QRectF());
QScriptValue::PropertyFlags getter = QScriptValue::PropertyGetter;
QScriptValue::PropertyFlags setter = QScriptValue::PropertySetter;
proto.setProperty("adjust", eng->newFunction(adjust));
proto.setProperty("adjusted", eng->newFunction(adjusted), getter);
proto.setProperty("translate", eng->newFunction(translate));
proto.setProperty("setCoords", eng->newFunction(setCoords));
proto.setProperty("setRect", eng->newFunction(setRect));
proto.setProperty("contains", eng->newFunction(contains));
proto.setProperty("moveBottom", eng->newFunction(moveBottom));
proto.setProperty("moveLeft", eng->newFunction(moveLeft));
proto.setProperty("moveRight", eng->newFunction(moveRight));
proto.setProperty("moveTo", eng->newFunction(moveTo));
proto.setProperty("moveTop", eng->newFunction(moveTop));
proto.setProperty("empty", eng->newFunction(empty), getter);
proto.setProperty("null", eng->newFunction(null), getter);
proto.setProperty("valid", eng->newFunction(valid), getter);
proto.setProperty("left", eng->newFunction(left), getter | setter);
proto.setProperty("top", eng->newFunction(top), getter | setter);
proto.setProperty("bottom", eng->newFunction(bottom), getter | setter);
proto.setProperty("right", eng->newFunction(right), getter | setter);
proto.setProperty("height", eng->newFunction(height), getter | setter);
proto.setProperty("width", eng->newFunction(width), getter | setter);
proto.setProperty("x", eng->newFunction(x), getter | setter);
proto.setProperty("y", eng->newFunction(y), getter | setter);
eng->setDefaultPrototype(qMetaTypeId<QRectF>(), proto);
eng->setDefaultPrototype(qMetaTypeId<QRectF*>(), proto);
return eng->newFunction(ctor, proto);
}

View File

@ -1,816 +0,0 @@
/*
* Copyright 2009 Aaron Seigo <aseigo@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 "scriptengine.h"
#include <QApplication>
#include <QDesktopWidget>
#include <QDir>
#include <QDirIterator>
#include <QFile>
#include <QFileInfo>
#include <QScriptValueIterator>
#include <QStandardPaths>
#include <QFutureWatcher>
#include <QDebug>
#include <klocalizedstring.h>
#include <kmimetypetrader.h>
#include <kservicetypetrader.h>
#include <kshell.h>
// KIO
//#include <kemailsettings.h> // no camelcase include
#include <Plasma/Applet>
#include <Plasma/Containment>
#include <Plasma/Package>
#include <Plasma/PluginLoader>
#include <qstandardpaths.h>
#include "appinterface.h"
#include "containment.h"
#include "configgroup.h"
#include "i18n.h"
//#include "packages.h"
#include "widget.h"
#include "../activity.h"
#include "../shellcorona.h"
QScriptValue constructQRectFClass(QScriptEngine *engine);
namespace WorkspaceScripting
{
ScriptEngine::ScriptEngine(ShellCorona *corona, QObject *parent)
: QScriptEngine(parent),
m_corona(corona)
{
Q_ASSERT(m_corona);
AppInterface *interface = new AppInterface(this);
connect(interface, SIGNAL(print(QString)), this, SIGNAL(print(QString)));
m_scriptSelf = newQObject(interface, QScriptEngine::QtOwnership,
QScriptEngine::ExcludeSuperClassProperties |
QScriptEngine::ExcludeSuperClassMethods);
setupEngine();
connect(this, SIGNAL(signalHandlerException(QScriptValue)), this, SLOT(exception(QScriptValue)));
bindI18N(this);
}
ScriptEngine::~ScriptEngine()
{
}
QScriptValue ScriptEngine::desktopById(QScriptContext *context, QScriptEngine *engine)
{
if (context->argumentCount() == 0) {
return context->throwError(i18n("activityById requires an id"));
}
const uint id = context->argument(0).toInt32();
ScriptEngine *env = envFor(engine);
foreach (Plasma::Containment *c, env->m_corona->containments()) {
if (c->id() == id && !isPanel(c)) {
return env->wrap(c);
}
}
return engine->undefinedValue();
}
QScriptValue ScriptEngine::desktopsForActivity(QScriptContext *context, QScriptEngine *engine)
{
if (context->argumentCount() == 0) {
return context->throwError(i18n("containmentsByActivity requires an id"));
}
QScriptValue containments = engine->newArray();
int count = 0;
const QString id = context->argument(0).toString();
ScriptEngine *env = envFor(engine);
foreach (Plasma::Containment *c, env->m_corona->containments()) {
if (c->activity() == id && !isPanel(c)) {
containments.setProperty(count, env->wrap(c));
++count;
}
}
containments.setProperty("length", count);
return containments;
}
QScriptValue ScriptEngine::desktopForScreen(QScriptContext *context, QScriptEngine *engine)
{
if (context->argumentCount() == 0) {
return context->throwError(i18n("activityForScreen requires a screen id"));
}
const uint screen = context->argument(0).toInt32();
ScriptEngine *env = envFor(engine);
return env->wrap(env->m_corona->containmentForScreen(screen));
}
QScriptValue ScriptEngine::createActivity(QScriptContext *context, QScriptEngine *engine)
{
if (context->argumentCount() < 0) {
return context->throwError(i18n("createActivity required the activity name"));
}
const QString name = context->argument(0).toString();
const QString plugin = context->argument(1).toString();
KActivities::Controller controller;
QFuture<QString> id = controller.addActivity(name);
QEventLoop loop;
QFutureWatcher<QString> *watcher = new QFutureWatcher<QString>();
connect(watcher, &QFutureWatcherBase::finished, &loop, &QEventLoop::quit);
watcher->setFuture(id);
loop.exec();
ScriptEngine *env = envFor(engine);
Activity *a = new Activity(id, env->m_corona);
if (!plugin.isEmpty()) {
a->setDefaultPlugin(plugin);
}
env->m_corona->insertActivity(id, a);
return QScriptValue(id.result());
}
QScriptValue ScriptEngine::setCurrentActivity(QScriptContext *context, QScriptEngine *engine)
{
if (context->argumentCount() < 0) {
return context->throwError(i18n("setCurrentActivity required the activity id"));
}
const QString id = context->argument(0).toString();
KActivities::Controller controller;
QFuture<bool> task = controller.setCurrentActivity(id);
QEventLoop loop;
QFutureWatcher<bool> *watcher = new QFutureWatcher<bool>();
connect(watcher, &QFutureWatcherBase::finished, &loop, &QEventLoop::quit);
watcher->setFuture(task);
loop.exec();
return QScriptValue(task.result());
}
QScriptValue ScriptEngine::activities(QScriptContext *context, QScriptEngine *engine)
{
KActivities::Consumer consumer;
return qScriptValueFromSequence(engine, consumer.activities());
}
QScriptValue ScriptEngine::newPanel(QScriptContext *context, QScriptEngine *engine)
{
return createContainment("Panel", "org.kde.panel", context, engine);
}
QScriptValue ScriptEngine::createContainment(const QString &type, const QString &defaultPlugin,
QScriptContext *context, QScriptEngine *engine)
{
QString plugin = context->argumentCount() > 0 ? context->argument(0).toString() :
defaultPlugin;
bool exists = false;
const KPluginInfo::List list = Plasma::PluginLoader::listContainmentsOfType(type);
foreach (const KPluginInfo &info, list) {
if (info.pluginName() == plugin) {
exists = true;
break;
}
}
if (!exists) {
return context->throwError(i18n("Could not find a plugin for %1 named %2.", type, plugin));
}
ScriptEngine *env = envFor(engine);
Plasma::Containment *c = env->m_corona->createContainment(plugin);
if (c) {
if (type == "Panel") {
// some defaults
c->setFormFactor(Plasma::Types::Horizontal);
c->setLocation(Plasma::Types::TopEdge);
}
c->updateConstraints(Plasma::Types::AllConstraints | Plasma::Types::StartupCompletedConstraint);
c->flushPendingConstraintsEvents();
}
return env->wrap(c);
}
QScriptValue ScriptEngine::wrap(Plasma::Applet *w)
{
Widget *wrapper = new Widget(w);
QScriptValue v = newQObject(wrapper, QScriptEngine::ScriptOwnership,
QScriptEngine::ExcludeSuperClassProperties |
QScriptEngine::ExcludeSuperClassMethods);
return v;
}
QScriptValue ScriptEngine::wrap(Plasma::Containment *c)
{
Containment *wrapper = new Containment(c);
return wrap(wrapper);
}
QScriptValue ScriptEngine::wrap(Containment *c)
{
QScriptValue v = newQObject(c, QScriptEngine::ScriptOwnership,
QScriptEngine::ExcludeSuperClassProperties |
QScriptEngine::ExcludeSuperClassMethods);
v.setProperty("widgetById", newFunction(Containment::widgetById));
v.setProperty("addWidget", newFunction(Containment::addWidget));
v.setProperty("widgets", newFunction(Containment::widgets));
return v;
}
int ScriptEngine::defaultPanelScreen() const
{
return qApp ? qApp->desktop()->primaryScreen() : 0;
}
ScriptEngine *ScriptEngine::envFor(QScriptEngine *engine)
{
QObject *object = engine->globalObject().toQObject();
Q_ASSERT(object);
AppInterface *interface = qobject_cast<AppInterface *>(object);
Q_ASSERT(interface);
ScriptEngine *env = qobject_cast<ScriptEngine *>(interface->parent());
Q_ASSERT(env);
return env;
}
QScriptValue ScriptEngine::panelById(QScriptContext *context, QScriptEngine *engine)
{
if (context->argumentCount() == 0) {
return context->throwError(i18n("panelById requires an id"));
}
const uint id = context->argument(0).toInt32();
ScriptEngine *env = envFor(engine);
foreach (Plasma::Containment *c, env->m_corona->containments()) {
if (c->id() == id && isPanel(c)) {
return env->wrap(c);
}
}
return engine->undefinedValue();
}
QScriptValue ScriptEngine::panels(QScriptContext *context, QScriptEngine *engine)
{
Q_UNUSED(context)
QScriptValue panels = engine->newArray();
ScriptEngine *env = envFor(engine);
int count = 0;
foreach (Plasma::Containment *c, env->m_corona->containments()) {
if (isPanel(c)) {
panels.setProperty(count, env->wrap(c));
++count;
}
}
panels.setProperty("length", count);
return panels;
}
QScriptValue ScriptEngine::fileExists(QScriptContext *context, QScriptEngine *engine)
{
Q_UNUSED(engine)
if (context->argumentCount() == 0) {
return false;
}
const QString path = context->argument(0).toString();
if (path.isEmpty()) {
return false;
}
QFile f(KShell::tildeExpand(path));
return f.exists();
}
QScriptValue ScriptEngine::loadTemplate(QScriptContext *context, QScriptEngine *engine)
{
Q_UNUSED(engine)
if (context->argumentCount() == 0) {
// qDebug() << "no arguments";
return false;
}
const QString layout = context->argument(0).toString();
if (layout.isEmpty() || layout.contains("'")) {
// qDebug() << "layout is empty";
return false;
}
const QString constraint = QString("[X-Plasma-Shell] == '%1' and [X-KDE-PluginInfo-Name] == '%2'")
.arg(qApp->applicationName(),layout);
KService::List offers = KServiceTypeTrader::self()->query("Plasma/LayoutTemplate", constraint);
if (offers.isEmpty()) {
// qDebug() << "offers fail" << constraint;
return false;
}
Plasma::Package package = Plasma::PluginLoader::self()->loadPackage("Plasma/LayoutTemplate");
KPluginInfo info(offers.first());
const QString path = QStandardPaths::locate(QStandardPaths::GenericDataLocation, package.defaultPackageRoot() + '/' + info.pluginName() + '/');
if (path.isEmpty()) {
// qDebug() << "script path is empty";
return false;
}
package.setPath(path);
const QString scriptFile = package.filePath("mainscript");
if (scriptFile.isEmpty()) {
// qDebug() << "scriptfile is empty";
return false;
}
QFile file(scriptFile);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qWarning() << i18n("Unable to load script file: %1", path);
return false;
}
QString script = file.readAll();
if (script.isEmpty()) {
// qDebug() << "script is empty";
return false;
}
ScriptEngine *env = envFor(engine);
env->globalObject().setProperty("templateName", env->newVariant(info.name()), QScriptValue::ReadOnly | QScriptValue::Undeletable);
env->globalObject().setProperty("templateComment", env->newVariant(info.comment()), QScriptValue::ReadOnly | QScriptValue::Undeletable);
QScriptValue rv = env->newObject();
QScriptContext *ctx = env->pushContext();
ctx->setThisObject(rv);
env->evaluateScript(script, path);
env->popContext();
return rv;
}
QScriptValue ScriptEngine::applicationExists(QScriptContext *context, QScriptEngine *engine)
{
Q_UNUSED(engine)
if (context->argumentCount() == 0) {
return false;
}
const QString application = context->argument(0).toString();
if (application.isEmpty()) {
return false;
}
// first, check for it in $PATH
if (!QStandardPaths::findExecutable(application).isEmpty()) {
return true;
}
if (KService::serviceByStorageId(application)) {
return true;
}
if (application.contains("'")) {
// apostrophes just screw up the trader lookups below, so check for it
return false;
}
// next, consult ksycoca for an app by that name
if (!KServiceTypeTrader::self()->query("Application", QString("Name =~ '%1'").arg(application)).isEmpty()) {
return true;
}
// next, consult ksycoca for an app by that generic name
if (!KServiceTypeTrader::self()->query("Application", QString("GenericName =~ '%1'").arg(application)).isEmpty()) {
return true;
}
return false;
}
QString ScriptEngine::onlyExec(const QString &commandLine)
{
if (commandLine.isEmpty()) {
return commandLine;
}
return KShell::splitArgs(commandLine, KShell::TildeExpand).first();
}
QScriptValue ScriptEngine::defaultApplication(QScriptContext *context, QScriptEngine *engine)
{
Q_UNUSED(engine)
if (context->argumentCount() == 0) {
return false;
}
const QString application = context->argument(0).toString();
if (application.isEmpty()) {
return false;
}
const bool storageId = context->argumentCount() < 2 ? false : context->argument(1).toBool();
// FIXME: there are some pretty horrible hacks below, in the sense that they assume a very
// specific implementation system. there is much room for improvement here. see
// kdebase-runtime/kcontrol/componentchooser/ for all the gory details ;)
if (application.compare("mailer", Qt::CaseInsensitive) == 0) {
// KEMailSettings settings;
// in KToolInvocation, the default is kmail; but let's be friendlier :)
// QString command = settings.getSetting(KEMailSettings::ClientProgram);
QString command;
if (command.isEmpty()) {
if (KService::Ptr kontact = KService::serviceByStorageId("kontact")) {
return storageId ? kontact->storageId() : onlyExec(kontact->exec());
} else if (KService::Ptr kmail = KService::serviceByStorageId("kmail")) {
return storageId ? kmail->storageId() : onlyExec(kmail->exec());
}
}
if (!command.isEmpty()) {
//if (settings.getSetting(KEMailSettings::ClientTerminal) == "true") {
if (false) {
KConfigGroup confGroup(KSharedConfig::openConfig(), "General");
const QString preferredTerminal = confGroup.readPathEntry("TerminalApplication", QString::fromLatin1("konsole"));
command = preferredTerminal + QString::fromLatin1(" -e ") + command;
}
return command;
}
} else if (application.compare("browser", Qt::CaseInsensitive) == 0) {
KConfigGroup config(KSharedConfig::openConfig(), "General");
QString browserApp = config.readPathEntry("BrowserApplication", QString());
if (browserApp.isEmpty()) {
const KService::Ptr htmlApp = KMimeTypeTrader::self()->preferredService(QLatin1String("text/html"));
if (htmlApp) {
browserApp = storageId ? htmlApp->storageId() : htmlApp->exec();
}
} else if (browserApp.startsWith('!')) {
browserApp = browserApp.mid(1);
}
return onlyExec(browserApp);
} else if (application.compare("terminal", Qt::CaseInsensitive) == 0) {
KConfigGroup confGroup(KSharedConfig::openConfig(), "General");
return onlyExec(confGroup.readPathEntry("TerminalApplication", QString::fromLatin1("konsole")));
} else if (application.compare("filemanager", Qt::CaseInsensitive) == 0) {
KService::Ptr service = KMimeTypeTrader::self()->preferredService("inode/directory");
if (service) {
return storageId ? service->storageId() : onlyExec(service->exec());
}
} else if (application.compare("windowmanager", Qt::CaseInsensitive) == 0) {
KConfig cfg("ksmserverrc", KConfig::NoGlobals);
KConfigGroup confGroup(&cfg, "General");
return onlyExec(confGroup.readEntry("windowManager", QString::fromLatin1("kwin")));
} else if (KService::Ptr service = KMimeTypeTrader::self()->preferredService(application)) {
return storageId ? service->storageId() : onlyExec(service->exec());
} else {
// try the files in share/apps/kcm_componentchooser/
const QStringList services = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, "kcm_componentchooser/");
qDebug() << "ok, trying in" << services;
foreach (const QString &service, services) {
if (!service.endsWith(".desktop")) {
continue;
}
KConfig config(service, KConfig::SimpleConfig);
KConfigGroup cg = config.group(QByteArray());
const QString type = cg.readEntry("valueName", QString());
//qDebug() << " checking" << service << type << application;
if (type.compare(application, Qt::CaseInsensitive) == 0) {
KConfig store(cg.readPathEntry("storeInFile", "null"));
KConfigGroup storeCg(&store, cg.readEntry("valueSection", QString()));
const QString exec = storeCg.readPathEntry(cg.readEntry("valueName", "kcm_componenchooser_null"),
cg.readEntry("defaultImplementation", QString()));
if (!exec.isEmpty()) {
return exec;
}
break;
}
}
}
return false;
}
QScriptValue ScriptEngine::applicationPath(QScriptContext *context, QScriptEngine *engine)
{
Q_UNUSED(engine)
if (context->argumentCount() == 0) {
return false;
}
const QString application = context->argument(0).toString();
if (application.isEmpty()) {
return false;
}
// first, check for it in $PATH
const QString path = QStandardPaths::findExecutable(application);
if (!path.isEmpty()) {
return path;
}
if (KService::Ptr service = KService::serviceByStorageId(application)) {
return QStandardPaths::locate(QStandardPaths::ApplicationsLocation, service->entryPath());
}
if (application.contains("'")) {
// apostrophes just screw up the trader lookups below, so check for it
return QString();
}
// next, consult ksycoca for an app by that name
KService::List offers = KServiceTypeTrader::self()->query("Application", QString("Name =~ '%1'").arg(application));
if (offers.isEmpty()) {
// next, consult ksycoca for an app by that generic name
offers = KServiceTypeTrader::self()->query("Application", QString("GenericName =~ '%1'").arg(application));
}
if (!offers.isEmpty()) {
KService::Ptr offer = offers.first();
return QStandardPaths::locate(QStandardPaths::ApplicationsLocation, offer->entryPath());
}
return QString();
}
QScriptValue ScriptEngine::userDataPath(QScriptContext *context, QScriptEngine *engine)
{
Q_UNUSED(engine)
if (context->argumentCount() == 0) {
return QDir::homePath();
}
const QString type = context->argument(0).toString();
if (type.isEmpty()) {
return QDir::homePath();
}
QStandardPaths::StandardLocation location = QStandardPaths::GenericDataLocation;
if (type.compare("desktop", Qt::CaseInsensitive) == 0) {
location = QStandardPaths::DesktopLocation;
} else if (type.compare("documents", Qt::CaseInsensitive) == 0) {
location = QStandardPaths::DocumentsLocation;
} else if (type.compare("music", Qt::CaseInsensitive) == 0) {
location = QStandardPaths::MusicLocation;
} else if (type.compare("video", Qt::CaseInsensitive) == 0) {
location = QStandardPaths::MoviesLocation;
} else if (type.compare("downloads", Qt::CaseInsensitive) == 0) {
location = QStandardPaths::DownloadLocation;
} else if (type.compare("pictures", Qt::CaseInsensitive) == 0) {
location = QStandardPaths::PicturesLocation;
} else if (type.compare("config", Qt::CaseInsensitive) == 0) {
location = QStandardPaths::GenericConfigLocation;
}
if (context->argumentCount() > 1) {
QString loc = QStandardPaths::writableLocation(location);
loc.append(QDir::separator());
loc.append(context->argument(1).toString());
return loc;
}
const QStringList &locations = QStandardPaths::standardLocations(location);
return locations.count() ? locations.first() : QString();
}
QScriptValue ScriptEngine::knownWallpaperPlugins(QScriptContext *context, QScriptEngine *engine)
{
Q_UNUSED(engine)
QString formFactor;
if (context->argumentCount() > 0) {
formFactor = context->argument(0).toString();
}
QString constraint;
if (!formFactor.isEmpty()) {
constraint.append("[X-Plasma-FormFactors] ~~ '").append(formFactor).append("'");
}
KService::List services = KServiceTypeTrader::self()->query("Plasma/Wallpaper", constraint);
QScriptValue rv = engine->newArray(services.size());
foreach (const KService::Ptr service, services) {
QList<KServiceAction> modeActions = service->actions();
QScriptValue modes = engine->newArray(modeActions.size());
int i = 0;
foreach (const KServiceAction &action, modeActions) {
modes.setProperty(i++, action.name());
}
rv.setProperty(service->name(), modes);
}
return rv;
}
QScriptValue ScriptEngine::configFile(QScriptContext *context, QScriptEngine *engine)
{
ConfigGroup *file = 0;
if (context->argumentCount() > 0) {
if (context->argument(0).isString()) {
file = new ConfigGroup;
file->setFile(context->argument(0).toString());
if (context->argumentCount() > 1) {
file->setGroup(context->argument(1).toString());
}
} else if (ConfigGroup *parent= qobject_cast<ConfigGroup *>(context->argument(0).toQObject())) {
file = new ConfigGroup(parent);
}
} else {
file = new ConfigGroup;
}
QScriptValue v = engine->newQObject(file,
QScriptEngine::ScriptOwnership,
QScriptEngine::ExcludeSuperClassProperties |
QScriptEngine::ExcludeSuperClassMethods);
return v;
}
void ScriptEngine::setupEngine()
{
QScriptValue v = globalObject();
QScriptValueIterator it(v);
while (it.hasNext()) {
it.next();
// we provide our own print implementation, but we want the rest
if (it.name() != "print") {
m_scriptSelf.setProperty(it.name(), it.value());
}
}
m_scriptSelf.setProperty("QRectF", constructQRectFClass(this));
m_scriptSelf.setProperty("createActivity", newFunction(ScriptEngine::createActivity));
m_scriptSelf.setProperty("setCurrentActivity", newFunction(ScriptEngine::setCurrentActivity));
m_scriptSelf.setProperty("activities", newFunction(ScriptEngine::activities));
m_scriptSelf.setProperty("Panel", newFunction(ScriptEngine::newPanel, newObject()));
m_scriptSelf.setProperty("desktopsForActivity", newFunction(ScriptEngine::desktopsForActivity));
m_scriptSelf.setProperty("desktops", newFunction(ScriptEngine::desktops));
m_scriptSelf.setProperty("desktopById", newFunction(ScriptEngine::desktopById));
m_scriptSelf.setProperty("desktopForScreen", newFunction(ScriptEngine::desktopForScreen));
m_scriptSelf.setProperty("panelById", newFunction(ScriptEngine::panelById));
m_scriptSelf.setProperty("panels", newFunction(ScriptEngine::panels));
m_scriptSelf.setProperty("fileExists", newFunction(ScriptEngine::fileExists));
m_scriptSelf.setProperty("loadTemplate", newFunction(ScriptEngine::loadTemplate));
m_scriptSelf.setProperty("applicationExists", newFunction(ScriptEngine::applicationExists));
m_scriptSelf.setProperty("defaultApplication", newFunction(ScriptEngine::defaultApplication));
m_scriptSelf.setProperty("userDataPath", newFunction(ScriptEngine::userDataPath));
m_scriptSelf.setProperty("applicationPath", newFunction(ScriptEngine::applicationPath));
m_scriptSelf.setProperty("knownWallpaperPlugins", newFunction(ScriptEngine::knownWallpaperPlugins));
m_scriptSelf.setProperty("ConfigFile", newFunction(ScriptEngine::configFile));
setGlobalObject(m_scriptSelf);
}
bool ScriptEngine::isPanel(const Plasma::Containment *c)
{
if (!c) {
return false;
}
return c->containmentType() == Plasma::Types::PanelContainment ||
c->containmentType() == Plasma::Types::CustomPanelContainment;
}
QScriptValue ScriptEngine::desktops(QScriptContext *context, QScriptEngine *engine)
{
Q_UNUSED(context)
QScriptValue containments = engine->newArray();
ScriptEngine *env = envFor(engine);
int count = 0;
foreach (Plasma::Containment *c, env->corona()->containments()) {
if (!isPanel(c)) {
containments.setProperty(count, env->wrap(c));
++count;
}
}
containments.setProperty("length", count);
return containments;
}
ShellCorona *ScriptEngine::corona() const
{
return m_corona;
}
bool ScriptEngine::evaluateScript(const QString &script, const QString &path)
{
//qDebug() << "evaluating" << m_editor->toPlainText();
evaluate(script, path);
if (hasUncaughtException()) {
//qDebug() << "catch the exception!";
QString error = i18n("Error: %1 at line %2\n\nBacktrace:\n%3",
uncaughtException().toString(),
QString::number(uncaughtExceptionLineNumber()),
uncaughtExceptionBacktrace().join("\n "));
emit printError(error);
return false;
}
return true;
}
void ScriptEngine::exception(const QScriptValue &value)
{
//qDebug() << "exception caught!" << value.toVariant();
emit printError(value.toVariant().toString());
}
QStringList ScriptEngine::pendingUpdateScripts(ShellCorona *corona)
{
if (!corona->package().metadata().isValid()) {
qWarning() << "Warning: corona package invalid";
return QStringList();
}
const QString appName = corona->package().metadata().pluginName();
QStringList scripts;
const QStringList dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, appName + QStringLiteral("/kpartplugins"), QStandardPaths::LocateDirectory);
Q_FOREACH(const QString& dir, dirs) {
QDirIterator it(dir, QStringList() << QStringLiteral("*.js"));
while (it.hasNext()) {
scripts.append(it.next());
}
}
QStringList scriptPaths;
if (scripts.isEmpty()) {
//qDebug() << "no update scripts";
return scriptPaths;
}
KConfigGroup cg(KSharedConfig::openConfig(), "Updates");
QStringList performed = cg.readEntry("performed", QStringList());
const QString localXdgDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
foreach (const QString &script, scripts) {
if (performed.contains(script)) {
continue;
}
if (script.startsWith(localXdgDir)) {
// qDebug() << "skipping user local script: " << script;
continue;
}
scriptPaths.append(script);
performed.append(script);
}
cg.writeEntry("performed", performed);
KSharedConfig::openConfig()->sync();
return scriptPaths;
}
}
#include "scriptengine.moc"

View File

@ -1,107 +0,0 @@
/*
* Copyright 2009 Aaron Seigo <aseigo@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 SCRIPTENGINE
#define SCRIPTENGINE
#include <QScriptEngine>
#include <QScriptValue>
#include <kactivities/controller.h>
#include "../shellcorona.h"
namespace Plasma
{
class Applet;
class Containment;
} // namespace Plasma
namespace WorkspaceScripting
{
class Containment;
class ScriptEngine : public QScriptEngine
{
Q_OBJECT
public:
ScriptEngine(ShellCorona *corona, QObject *parent = 0);
~ScriptEngine();
static QStringList pendingUpdateScripts(ShellCorona *corona);
ShellCorona *corona() const;
bool evaluateScript(const QString &script, const QString &path = QString());
QScriptValue wrap(Plasma::Applet *w);
virtual QScriptValue wrap(Plasma::Containment *c);
QScriptValue wrap(Containment *c);
virtual int defaultPanelScreen() const;
static bool isPanel(const Plasma::Containment *c);
static ScriptEngine *envFor(QScriptEngine *engine);
Q_SIGNALS:
void print(const QString &string);
void printError(const QString &string);
private:
void setupEngine();
static QString onlyExec(const QString &commandLine);
// containment accessors
static QStringList availableContainments(const QString &type);
static QScriptValue createActivity(QScriptContext *context, QScriptEngine *engine);
static QScriptValue setCurrentActivity(QScriptContext *context, QScriptEngine *engine);
static QScriptValue activities(QScriptContext *context, QScriptEngine *engine);
static QScriptValue newPanel(QScriptContext *context, QScriptEngine *engine);
static QScriptValue desktopsForActivity(QScriptContext *context, QScriptEngine *engine);
static QScriptValue desktops(QScriptContext *context, QScriptEngine *engine);
static QScriptValue desktopById(QScriptContext *context, QScriptEngine *engine);
static QScriptValue desktopForScreen(QScriptContext *context, QScriptEngine *engine);
static QScriptValue panelById(QScriptContext *context, QScriptEngine *engine);
static QScriptValue panels(QScriptContext *context, QScriptEngine *engine);
static QScriptValue fileExists(QScriptContext *context, QScriptEngine *engine);
static QScriptValue loadTemplate(QScriptContext *context, QScriptEngine *engine);
static QScriptValue applicationExists(QScriptContext *context, QScriptEngine *engine);
static QScriptValue defaultApplication(QScriptContext *context, QScriptEngine *engine);
static QScriptValue applicationPath(QScriptContext *context, QScriptEngine *engine);
static QScriptValue userDataPath(QScriptContext *context, QScriptEngine *engine);
static QScriptValue knownWallpaperPlugins(QScriptContext *context, QScriptEngine *engine);
static QScriptValue configFile(QScriptContext *context, QScriptEngine *engine);
// helpers
static QScriptValue createContainment(const QString &type, const QString &defautPlugin,
QScriptContext *context, QScriptEngine *engine);
private Q_SLOTS:
void exception(const QScriptValue &value);
private:
ShellCorona *m_corona;
QScriptValue m_scriptSelf;
};
static const int PLASMA_DESKTOP_SCRIPTING_VERSION = 20;
}
#endif

View File

@ -1,180 +0,0 @@
/*
* Copyright 2009 Aaron Seigo <aseigo@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 "widget.h"
#include <QAction>
#include <Plasma/Applet>
#include <Plasma/Containment>
#include <Plasma/Corona>
namespace WorkspaceScripting
{
class Widget::Private
{
public:
Private()
{
}
QWeakPointer<Plasma::Applet> applet;
};
Widget::Widget(Plasma::Applet *applet, QObject *parent)
: Applet(parent),
d(new Widget::Private)
{
d->applet = applet;
setCurrentConfigGroup(QStringList());
setCurrentGlobalConfigGroup(QStringList());
}
Widget::~Widget()
{
reloadConfigIfNeeded();
delete d;
}
uint Widget::id() const
{
if (d->applet) {
return d->applet.data()->id();
}
return 0;
}
QString Widget::type() const
{
if (d->applet) {
return d->applet.data()->pluginInfo().pluginName();
}
return QString();
}
void Widget::remove()
{
if (d->applet) {
d->applet.data()->destroy();
d->applet.clear();
}
}
void Widget::setGlobalShortcut(const QString &shortcut)
{
if (d->applet) {
d->applet.data()->setGlobalShortcut(QKeySequence(shortcut));
}
}
QString Widget::globalShorcut() const
{
if (d->applet) {
return d->applet.data()->globalShortcut().toString();
}
return QString();
}
Plasma::Applet *Widget::applet() const
{
return d->applet.data();
}
int Widget::index() const
{
if (!d->applet) {
return -1;
}
Plasma::Applet *applet = d->applet.data();
Plasma::Containment *c = applet->containment();
if (!c) {
return -1;
}
/*QGraphicsLayout *layout = c->layout();
if (!layout) {
return - 1;
}
for (int i = 0; i < layout->count(); ++i) {
if (layout->itemAt(i) == applet) {
return i;
}
}*/
return -1;
}
void Widget::setIndex(int index)
{
if (!d->applet) {
return;
}
Plasma::Applet *applet = d->applet.data();
Plasma::Containment *c = applet->containment();
if (!c) {
return;
}
/*
//FIXME: this is hackish. would be nice to define this for gridlayouts too
QGraphicsLinearLayout *layout = dynamic_cast<QGraphicsLinearLayout *>(c->layout());
if (!layout) {
return;
}
layout->insertItem(index, applet);*/
}
QRectF Widget::geometry() const
{
/*if (d->applet) {
return d->applet.data()->geometry();
}
*/
return QRectF();
}
void Widget::setGeometry(const QRectF &geometry)
{
/*if (d->applet) {
d->applet.data()->setGeometry(geometry);
KConfigGroup cg = d->applet.data()->config().parent();
if (cg.isValid()) {
cg.writeEntry("geometry", geometry);
}
}*/
}
void Widget::showConfigurationInterface()
{
/* if (d->applet) {
d->applet.data()->showConfigurationInterface();
}*/
}
}
#include "widget.moc"

View File

@ -1,90 +0,0 @@
/*
* Copyright 2009 Aaron Seigo <aseigo@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 WIDGET
#define WIDGET
#include <QWeakPointer>
#include "applet.h"
namespace Plasma
{
class Applet;
} // namespace Plasma
namespace WorkspaceScripting
{
class Widget : public Applet
{
Q_OBJECT
Q_PROPERTY(QString type READ type)
Q_PROPERTY(QString version READ version)
Q_PROPERTY(int id READ id)
Q_PROPERTY(QStringList configKeys READ configKeys)
Q_PROPERTY(QStringList configGroups READ configGroups)
Q_PROPERTY(QStringList globalConfigKeys READ globalConfigKeys)
Q_PROPERTY(QStringList globalConfigGroups READ globalConfigGroups)
Q_PROPERTY(int index WRITE setIndex READ index)
Q_PROPERTY(QRectF geometry WRITE setGeometry READ geometry)
Q_PROPERTY(QStringList currentConfigGroup WRITE setCurrentConfigGroup READ currentConfigGroup)
Q_PROPERTY(QString globalShortcut WRITE setGlobalShortcut READ globalShorcut)
Q_PROPERTY(bool locked READ locked WRITE setLocked)
public:
Widget(Plasma::Applet *applet, QObject *parent = 0);
~Widget();
uint id() const;
QString type() const;
int index() const;
void setIndex(int index);
QRectF geometry() const;
void setGeometry(const QRectF &geometry);
void setGlobalShortcut(const QString &shortcut);
QString globalShorcut() const;
Plasma::Applet *applet() const;
public Q_SLOTS:
void remove();
void showConfigurationInterface();
// from the applet interface
QVariant readConfig(const QString &key, const QVariant &def = QString()) const { return Applet::readConfig(key, def); }
void writeConfig(const QString &key, const QVariant &value) { Applet::writeConfig(key, value); }
QVariant readGlobalConfig(const QString &key, const QVariant &def = QString()) const { return Applet::readGlobalConfig(key, def); }
void writeGlobalConfig(const QString &key, const QVariant &value) { Applet::writeGlobalConfig(key, value); }
void reloadConfig() { Applet::reloadConfig(); }
private:
class Private;
Private * const d;
};
}
#endif

View File

@ -1,874 +0,0 @@
/*
* Copyright 2008 Aaron Seigo <aseigo@kde.org>
* Copyright 2013 Sebastian Kügler <sebas@kde.org>
* Copyright 2013 Ivan Cukic <ivan.cukic@kde.org>
* Copyright 2013 Marco Martin <mart@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 "shellcorona.h"
#include <QApplication>
#include <QDebug>
#include <QMenu>
#include <QDesktopWidget>
#include <QQmlContext>
#include <QTimer>
#include <QDBusConnection>
#include <kactioncollection.h>
#include <klocalizedstring.h>
#include <Plasma/Package>
#include <Plasma/PluginLoader>
#include <kactivities/controller.h>
#include <kactivities/consumer.h>
#include <ksycoca.h>
#include <kservicetypetrader.h>
#include <KGlobalAccel>
#include <KAuthorized>
#include <KWindowSystem>
#include "config-ktexteditor.h" // HAVE_KTEXTEDITOR
#include "activity.h"
#include "desktopview.h"
#include "panelview.h"
#include "scripting/desktopscriptengine.h"
#include "widgetexplorer/widgetexplorer.h"
#include "configview.h"
#include "shellpluginloader.h"
#include "osd.h"
#if HAVE_KTEXTEDITOR
#include "interactiveconsole.h"
#endif
#include "plasmashelladaptor.h"
static const int s_configSyncDelay = 10000; // 10 seconds
class ShellCorona::Private {
public:
Private(ShellCorona *corona)
: q(corona),
activityController(new KActivities::Controller(q)),
activityConsumer(new KActivities::Consumer(q)),
addPanelAction(nullptr),
addPanelsMenu(nullptr)
{
appConfigSyncTimer.setSingleShot(true);
appConfigSyncTimer.setInterval(s_configSyncDelay);
connect(&appConfigSyncTimer, &QTimer::timeout, q, &ShellCorona::syncAppConfig);
waitingPanelsTimer.setSingleShot(true);
waitingPanelsTimer.setInterval(250);
connect(&waitingPanelsTimer, &QTimer::timeout, q, &ShellCorona::createWaitingPanels);
}
ShellCorona *q;
QString shell;
QList<DesktopView *> views;
KActivities::Controller *activityController;
KActivities::Consumer *activityConsumer;
QHash<const Plasma::Containment *, PanelView *> panelViews;
KConfigGroup desktopDefaultsConfig;
WorkspaceScripting::DesktopScriptEngine *scriptEngine;
QList<Plasma::Containment *> waitingPanels;
QHash<QString, Activity *> activities;
QHash<QString, QHash<int, Plasma::Containment *> > desktopContainments;
QAction *addPanelAction;
QMenu *addPanelsMenu;
Plasma::Package lookNFeelPackage;
#if HAVE_KTEXTEDITOR
QWeakPointer<InteractiveConsole> console;
#endif
QTimer waitingPanelsTimer;
QTimer appConfigSyncTimer;
};
WorkspaceScripting::DesktopScriptEngine * ShellCorona::scriptEngine() const
{
return d->scriptEngine;
}
ShellCorona::ShellCorona(QObject *parent)
: Plasma::Corona(parent),
d(new Private(this))
{
d->desktopDefaultsConfig = KConfigGroup(KSharedConfig::openConfig(package().filePath("defaults")), "Desktop");
new PlasmaShellAdaptor(this);
QDBusConnection dbus = QDBusConnection::sessionBus();
dbus.registerObject(QStringLiteral("/PlasmaShell"), this);
// Look for theme config in plasmarc, if it isn't configured, take the theme from the
// LookAndFeel package, if either is set, change the default theme
const QString themeGroupKey = QStringLiteral("Theme");
const QString themeNameKey = QStringLiteral("name");
QString themeName;
KConfigGroup plasmarc(KSharedConfig::openConfig("plasmarc"), themeGroupKey);
themeName = plasmarc.readEntry(themeNameKey, themeName);
if (themeName.isEmpty()) {
const KConfigGroup lnfCfg = KConfigGroup(KSharedConfig::openConfig(
lookAndFeelPackage().filePath("defaults")),
themeGroupKey
);
themeName = lnfCfg.readEntry(themeNameKey, themeName);
}
if (!themeName.isEmpty()) {
Plasma::Theme *t = new Plasma::Theme(this);
t->setThemeName(themeName);
}
connect(this, &ShellCorona::containmentAdded,
this, &ShellCorona::handleContainmentAdded);
d->scriptEngine = new WorkspaceScripting::DesktopScriptEngine(this, true);
connect(d->scriptEngine, &WorkspaceScripting::ScriptEngine::printError,
[=](const QString &msg) {
qWarning() << msg;
});
connect(d->scriptEngine, &WorkspaceScripting::ScriptEngine::print,
[=](const QString &msg) {
qDebug() << msg;
});
QAction *dashboardAction = actions()->add<QAction>("show dashboard");
QObject::connect(dashboardAction, &QAction::triggered,
this, &ShellCorona::setDashboardShown);
dashboardAction->setText(i18n("Show Dashboard"));
dashboardAction->setAutoRepeat(true);
dashboardAction->setCheckable(true);
dashboardAction->setIcon(QIcon::fromTheme("dashboard-show"));
dashboardAction->setData(Plasma::Types::ControlAction);
KGlobalAccel::self()->setDefaultShortcut(dashboardAction, QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_F12));
KGlobalAccel::self()->setShortcut(dashboardAction, QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_F12));
checkAddPanelAction();
connect(KSycoca::self(), SIGNAL(databaseChanged(QStringList)), this, SLOT(checkAddPanelAction(QStringList)));
//Activity stuff
QAction *activityAction = actions()->addAction("manage activities");
connect(activityAction, &QAction::triggered,
this, &ShellCorona::toggleActivityManager);
activityAction->setText(i18n("Activities..."));
activityAction->setIcon(QIcon::fromTheme("preferences-activities"));
activityAction->setData(Plasma::Types::ConfigureAction);
activityAction->setShortcut(QKeySequence("alt+d, alt+a"));
activityAction->setShortcutContext(Qt::ApplicationShortcut);
connect(d->activityConsumer, SIGNAL(currentActivityChanged(QString)), this, SLOT(currentActivityChanged(QString)));
connect(d->activityConsumer, SIGNAL(activityAdded(QString)), this, SLOT(activityAdded(QString)));
connect(d->activityConsumer, SIGNAL(activityRemoved(QString)), this, SLOT(activityRemoved(QString)));
new Osd(this);
}
ShellCorona::~ShellCorona()
{
qDeleteAll(d->views);
}
void ShellCorona::setShell(const QString &shell)
{
if (d->shell == shell) {
return;
}
unload();
d->shell = shell;
Plasma::Package package = Plasma::PluginLoader::self()->loadPackage("Plasma/Shell");
package.setPath(shell);
setPackage(package);
if (d->activityConsumer->serviceStatus() == KActivities::Consumer::Unknown) {
connect(d->activityConsumer, SIGNAL(serviceStatusChanged(Consumer::ServiceStatus)), SLOT(load()), Qt::UniqueConnection);
} else {
load();
}
}
QString ShellCorona::shell() const
{
return d->shell;
}
void ShellCorona::load()
{
if (d->shell.isEmpty() ||
d->activityConsumer->serviceStatus() == KActivities::Consumer::Unknown) {
return;
}
disconnect(d->activityConsumer, SIGNAL(serviceStatusChanged(Consumer::ServiceStatus)), this, SLOT(load()));
loadLayout("plasma-" + d->shell + "-appletsrc");
checkActivities();
if (containments().isEmpty()) {
loadDefaultLayout();
foreach(Plasma::Containment* containment, containments()) {
containment->setActivity(d->activityConsumer->currentActivity());
}
}
processUpdateScripts();
foreach(Plasma::Containment* containment, containments()) {
if (containment->formFactor() == Plasma::Types::Horizontal ||
containment->formFactor() == Plasma::Types::Vertical) {
if (!d->waitingPanels.contains(containment)) {
d->waitingPanels << containment;
}
} else {
//FIXME ideally fix this, or at least document the crap out of it
int screen = containment->lastScreen();
if (screen < 0) {
screen = d->desktopContainments[containment->activity()].count();
}
insertContainment(containment->activity(), screen, containment);
}
}
for (QScreen *screen : QGuiApplication::screens()) {
screenAdded(screen);
}
connect(qApp, &QGuiApplication::screenAdded,
this, &ShellCorona::screenAdded);
if (!d->waitingPanels.isEmpty()) {
d->waitingPanelsTimer.start();
}
}
void ShellCorona::unload()
{
if (d->shell.isEmpty()) {
return;
}
qDeleteAll(containments());
}
KSharedConfig::Ptr ShellCorona::applicationConfig()
{
return KSharedConfig::openConfig();
}
void ShellCorona::requestApplicationConfigSync()
{
d->appConfigSyncTimer.start();
}
void ShellCorona::loadDefaultLayout()
{
const QString script = package().filePath("defaultlayout");
QFile file(script);
if (file.open(QIODevice::ReadOnly | QIODevice::Text) ) {
QString code = file.readAll();
qDebug() << "evaluating startup script:" << script;
d->scriptEngine->evaluateScript(code);
}
}
void ShellCorona::processUpdateScripts()
{
foreach (const QString &script, WorkspaceScripting::ScriptEngine::pendingUpdateScripts(this)) {
d->scriptEngine->evaluateScript(script);
}
}
KActivities::Controller *ShellCorona::activityController()
{
return d->activityController;
}
int ShellCorona::numScreens() const
{
return QApplication::desktop()->screenCount();
}
QRect ShellCorona::screenGeometry(int id) const
{
DesktopView *view = 0;
foreach (DesktopView *v, d->views) {
if (v->containment() && v->containment()->screen() == id) {
view = v;
break;
}
}
if (view) {
return view->geometry();
} else {
return QApplication::desktop()->screenGeometry(id);
}
}
QRegion ShellCorona::availableScreenRegion(int id) const
{
DesktopView *view = 0;
foreach (DesktopView *v, d->views) {
if (v->containment() && v->containment()->screen() == id) {
view = v;
break;
}
}
if (view) {
QRegion r = view->geometry();
foreach (PanelView *v, d->panelViews.values()) {
if (v->containment()->screen() == id && v->visibilityMode() != PanelView::AutoHide) {
r -= v->geometry();
}
}
return r;
} else {
return QApplication::desktop()->availableGeometry(id);
}
}
QRect ShellCorona::availableScreenRect(int id) const
{
if (id < 0) {
id = 0;
}
QRect r(screenGeometry(id));
foreach (PanelView *view, d->panelViews.values()) {
if (view->containment()->screen() == id && view->visibilityMode() != PanelView::AutoHide) {
QRect v = view->geometry();
switch (view->location()) {
case Plasma::Types::TopEdge:
if (v.bottom() > r.top()) {
r.setTop(v.bottom());
}
break;
case Plasma::Types::BottomEdge:
if (v.top() < r.bottom()) {
r.setBottom(v.top());
}
break;
case Plasma::Types::LeftEdge:
if (v.right() > r.left()) {
r.setLeft(v.right());
}
break;
case Plasma::Types::RightEdge:
if (v.left() < r.right()) {
r.setRight(v.left());
}
break;
default:
break;
}
}
}
return r;
}
PanelView *ShellCorona::panelView(Plasma::Containment *containment) const
{
return d->panelViews.value(containment);
}
///// SLOTS
void ShellCorona::screenAdded(QScreen *screen)
{
DesktopView *view = new DesktopView(this, screen);
const QString currentActivity = d->activityController->currentActivity();
if (!d->views.isEmpty() && screen == QGuiApplication::primaryScreen()) {
DesktopView* oldPrimaryView = d->views.first();
QScreen* oldPrimaryScreen = oldPrimaryView->screen();
//move any panels that were preivously on the old primary screen to the new primary screen
foreach (PanelView *panelView, d->panelViews) {
if (oldPrimaryScreen==panelView->screen())
panelView->setScreen(screen);
}
Plasma::Containment* primaryContainment = oldPrimaryView->containment();
oldPrimaryView->setContainment(0);
view->setContainment(primaryContainment);
d->views.prepend(view);
view = oldPrimaryView;
} else {
d->views.append(view);
}
int screenNum = d->views.count()-1;
Plasma::Containment *containment = d->desktopContainments[currentActivity][screenNum];
if (!containment) {
containment = createContainmentForActivity(currentActivity, screenNum);
}
QAction *removeAction = containment->actions()->action("remove");
if (removeAction) {
removeAction->deleteLater();
}
view->setContainment(containment);
connect(screen, SIGNAL(destroyed(QObject*)), SLOT(screenRemoved(QObject*)));
view->show();
emit availableScreenRectChanged();
emit availableScreenRegionChanged();
}
Plasma::Containment* ShellCorona::createContainmentForActivity(const QString& activity, int screenNum)
{
if (d->desktopContainments.contains(activity) &&
d->desktopContainments[activity].contains(screenNum) &&
d->desktopContainments.value(activity).value(screenNum)) {
return d->desktopContainments[activity][screenNum];
}
QString plugin = "org.kde.desktopcontainment";
if (d->activities.contains(activity)) {
// plugin = d->activities.value(activity)->defaultPlugin();
}
Plasma::Containment* containment = createContainment(d->desktopDefaultsConfig.readEntry("Containment", plugin));
containment->setActivity(activity);
insertContainment(activity, screenNum, containment);
return containment;
}
void ShellCorona::screenRemoved(QObject *screen)
{
//desktop containments
for (auto i = d->views.begin(); i != d->views.end(); i++) {
if ((*i)->screen() == screen) {
d->views.erase(i);
(*i)->containment()->reactToScreenChange();
(*i)->deleteLater();
break;
}
}
//move all panels on a deleted screen to the primary screen
//FIXME: this will break when a second screen is added again
//as in plasma1, panel should be hidden, panelView deleted.
//possibly similar to exportLayout/importLayout of Activities
foreach (PanelView *view, d->panelViews) {
view->setScreen(QGuiApplication::primaryScreen());
}
emit availableScreenRectChanged();
emit availableScreenRegionChanged();
}
void ShellCorona::createWaitingPanels()
{
foreach (Plasma::Containment *cont, d->waitingPanels) {
d->panelViews[cont] = new PanelView(this);
//keep screen suggestions within bounds of screens we actually have
int screen = qBound(0, cont->lastScreen(), QGuiApplication::screens().size() -1);
d->panelViews[cont]->setScreen(QGuiApplication::screens()[screen]);
d->panelViews[cont]->setContainment(cont);
connect(cont, &PanelView::destroyed,
[=](QObject *obj) {
d->panelViews.remove(cont);
emit availableScreenRectChanged();
emit availableScreenRegionChanged();
});
}
d->waitingPanels.clear();
emit availableScreenRectChanged();
emit availableScreenRegionChanged();
}
void ShellCorona::handleContainmentAdded(Plasma::Containment* c)
{
connect(c, &Plasma::Containment::showAddWidgetsInterface,
this, &ShellCorona::toggleWidgetExplorer);
}
void ShellCorona::toggleWidgetExplorer()
{
const QPoint cursorPos = QCursor::pos();
foreach (DesktopView *view, d->views) {
if (view->screen()->geometry().contains(cursorPos)) {
//The view QML has to provide something to display the activity explorer
view->rootObject()->metaObject()->invokeMethod(view->rootObject(), "toggleWidgetExplorer", Q_ARG(QVariant, QVariant::fromValue(sender())));
return;
}
}
}
void ShellCorona::toggleActivityManager()
{
const QPoint cursorPos = QCursor::pos();
foreach (DesktopView *view, d->views) {
if (view->screen()->geometry().contains(cursorPos)) {
//The view QML has to provide something to display the activity explorer
view->rootObject()->metaObject()->invokeMethod(view->rootObject(), "toggleActivityManager");
return;
}
}
}
void ShellCorona::syncAppConfig()
{
qDebug() << "Syncing plasma-shellrc config";
applicationConfig()->sync();
}
void ShellCorona::setDashboardShown(bool show)
{
qDebug() << "TODO: Toggling dashboard view";
QAction *dashboardAction = actions()->action("show dashboard");
if (dashboardAction) {
dashboardAction->setText(show ? i18n("Hide Dashboard") : i18n("Show Dashboard"));
}
foreach (DesktopView *view, d->views) {
view->setDashboardShown(show);
}
}
void ShellCorona::toggleDashboard()
{
foreach (DesktopView *view, d->views) {
view->setDashboardShown(!view->isDashboardShown());
}
}
void ShellCorona::showInteractiveConsole()
{
if (KSharedConfig::openConfig()->isImmutable() || !KAuthorized::authorize("plasma-desktop/scripting_console")) {
return;
}
#if HAVE_KTEXTEDITOR
InteractiveConsole *console = d->console.data();
if (!console) {
d->console = console = new InteractiveConsole(this);
}
d->console.data()->setMode(InteractiveConsole::PlasmaConsole);
KWindowSystem::setOnDesktop(console->winId(), KWindowSystem::currentDesktop());
console->show();
console->raise();
KWindowSystem::forceActiveWindow(console->winId());
#endif
}
void ShellCorona::loadScriptInInteractiveConsole(const QString &script)
{
#if HAVE_KTEXTEDITOR
showInteractiveConsole();
if (d->console) {
d->console.data()->loadScript(script);
}
#endif
}
void ShellCorona::checkActivities()
{
KActivities::Consumer::ServiceStatus status = d->activityController->serviceStatus();
//qDebug() << "$%$%$#%$%$%Status:" << status;
if (status != KActivities::Consumer::Running) {
//panic and give up - better than causing a mess
qDebug() << "ShellCorona::checkActivities is called whilst activity daemon is still connecting";
return;
}
QStringList existingActivities = d->activityConsumer->activities();
foreach (const QString &id, existingActivities) {
activityAdded(id);
}
// Checking whether the result we got is valid. Just in case.
Q_ASSERT_X(!existingActivities.isEmpty(), "isEmpty", "There are no activities, and the service is running");
Q_ASSERT_X(existingActivities[0] != QStringLiteral("00000000-0000-0000-0000-000000000000"),
"null uuid", "There is a nulluuid activity present");
// Killing the unassigned containments
foreach (Plasma::Containment * cont, containments()) {
if ((cont->containmentType() == Plasma::Types::DesktopContainment ||
cont->containmentType() == Plasma::Types::CustomContainment) &&
!existingActivities.contains(cont->activity())) {
cont->destroy();
}
}
}
void ShellCorona::currentActivityChanged(const QString &newActivity)
{
qDebug() << "Activity changed:" << newActivity;
for (int i = 0; i < d->views.count(); ++i) {
Plasma::Containment* c = d->desktopContainments[newActivity][i];
if (!c) {
c = createContainmentForActivity(newActivity, i);
}
QAction *removeAction = c->actions()->action("remove");
if (removeAction) {
removeAction->deleteLater();
}
d->views[i]->setContainment(c);
}
}
void ShellCorona::activityAdded(const QString &id)
{
//TODO more sanity checks
if (d->activities.contains(id)) {
qDebug() << "you're late." << id;
return;
}
Activity *a = new Activity(id, this);
d->activities.insert(id, a);
}
void ShellCorona::activityRemoved(const QString &id)
{
Activity *a = d->activities.take(id);
a->deleteLater();
}
Activity *ShellCorona::activity(const QString &id)
{
return d->activities.value(id);
}
void ShellCorona::insertActivity(const QString &id, Activity *activity)
{
d->activities.insert(id, activity);
Plasma::Containment *c = createContainmentForActivity(id, -1);
c->config().writeEntry("lastScreen", 0);
}
void ShellCorona::checkAddPanelAction(const QStringList &sycocaChanges)
{
if (!sycocaChanges.isEmpty() && !sycocaChanges.contains("services")) {
return;
}
delete d->addPanelAction;
d->addPanelAction = 0;
delete d->addPanelsMenu;
d->addPanelsMenu = 0;
KPluginInfo::List panelContainmentPlugins = Plasma::PluginLoader::listContainmentsOfType("Panel");
const QString constraint = QString("[X-Plasma-Shell] == '%1' and 'panel' ~in [X-Plasma-ContainmentCategories]")
.arg(qApp->applicationName());
KService::List templates = KServiceTypeTrader::self()->query("Plasma/LayoutTemplate", constraint);
if (panelContainmentPlugins.count() + templates.count() == 1) {
d->addPanelAction = new QAction(i18n("Add Panel"), this);
d->addPanelAction->setData(Plasma::Types::AddAction);
connect(d->addPanelAction, SIGNAL(triggered(bool)), this, SLOT(addPanel()));
} else if (!panelContainmentPlugins.isEmpty()) {
d->addPanelsMenu = new QMenu;
d->addPanelAction = d->addPanelsMenu->menuAction();
d->addPanelAction->setText(i18n("Add Panel"));
d->addPanelAction->setData(Plasma::Types::AddAction);
qDebug() << "populateAddPanelsMenu" << panelContainmentPlugins.count();
connect(d->addPanelsMenu, SIGNAL(aboutToShow()), this, SLOT(populateAddPanelsMenu()));
connect(d->addPanelsMenu, SIGNAL(triggered(QAction*)), this, SLOT(addPanel(QAction*)));
}
if (d->addPanelAction) {
d->addPanelAction->setIcon(QIcon::fromTheme("list-add"));
actions()->addAction("add panel", d->addPanelAction);
}
}
void ShellCorona::addPanel()
{
KPluginInfo::List panelPlugins = Plasma::PluginLoader::listContainmentsOfType("Panel");
if (!panelPlugins.isEmpty()) {
addPanel(panelPlugins.first().pluginName());
}
}
void ShellCorona::addPanel(QAction *action)
{
const QString plugin = action->data().toString();
if (plugin.startsWith("plasma-desktop-template:")) {
d->scriptEngine->evaluateScript(plugin.right(plugin.length() - qstrlen("plasma-desktop-template:")));
} else if (!plugin.isEmpty()) {
addPanel(plugin);
}
}
void ShellCorona::addPanel(const QString &plugin)
{
Plasma::Containment *panel = createContainment(plugin);
if (!panel) {
return;
}
QList<Plasma::Types::Location> availableLocations;
availableLocations << Plasma::Types::LeftEdge << Plasma::Types::TopEdge << Plasma::Types::RightEdge << Plasma::Types::BottomEdge;
foreach (const Plasma::Containment *cont, d->panelViews.keys()) {
availableLocations.removeAll(cont->location());
}
Plasma::Types::Location loc;
if (availableLocations.isEmpty()) {
loc = Plasma::Types::TopEdge;
} else {
loc = availableLocations.first();
}
panel->setLocation(loc);
switch (loc) {
case Plasma::Types::LeftEdge:
case Plasma::Types::RightEdge:
panel->setFormFactor(Plasma::Types::Vertical);
break;
default:
panel->setFormFactor(Plasma::Types::Horizontal);
break;
}
d->waitingPanels << panel;
d->waitingPanelsTimer.start();
}
int ShellCorona::screenForContainment(const Plasma::Containment *containment) const
{
QScreen *screen = nullptr;
for (int i = 0; i < d->views.size(); i++) {
if (d->views[i]->containment() == containment) {
screen = d->views[i]->screen();
}
}
if (!screen) {
PanelView *view = d->panelViews[containment];
if (view) {
screen = view->screen();
}
}
return screen ? qApp->screens().indexOf(screen) : -1;
}
void ShellCorona::activityOpened()
{
Activity *activity = qobject_cast<Activity *>(sender());
if (activity) {
QList<Plasma::Containment*> cs = importLayout(activity->config());
for (Plasma::Containment *containment : cs) {
insertContainment(activity->name(), containment->lastScreen(), containment);
}
}
}
void ShellCorona::activityClosed()
{
Activity *activity = qobject_cast<Activity *>(sender());
if (activity) {
KConfigGroup cg = activity->config();
exportLayout(cg, d->desktopContainments.value(activity->name()).values());
}
}
void ShellCorona::activityRemoved()
{
//when an activity is removed delete all associated desktop containments
Activity *activity = qobject_cast<Activity *>(sender());
if (activity) {
QHash< int, Plasma::Containment* > containmentHash = d->desktopContainments.take(activity->name());
for (auto a : containmentHash) {
a->destroy();
}
}
}
void ShellCorona::insertContainment(const QString &activity, int screenNum, Plasma::Containment* containment)
{
d->desktopContainments[activity][screenNum] = containment;
//when a containment gets deleted update our map of containments
connect(containment, &QObject::destroyed, [=](QObject *obj) {
// when QObject::destroyed arrives, ~Plasma::Containment has run,
// members of Containment are not accessible anymore,
// so keep ugly bookeeping by hand
auto containment = static_cast<Plasma::Containment*>(obj);
for (auto a : d->desktopContainments) {
QMutableHashIterator<int, Plasma::Containment *> it(a);
while (it.hasNext()) {
it.next();
if (it.value() == containment) {
it.remove();
return;
}
}
}
});
}
Plasma::Package ShellCorona::lookAndFeelPackage() const
{
if (!d->lookNFeelPackage.isValid()) {
d->lookNFeelPackage = ShellPluginLoader::self()->loadPackage("Plasma/LookAndFeel");
//TODO: make loading from config once we have some UI for setting the package
d->lookNFeelPackage.setPath("org.kde.lookandfeel");
}
return d->lookNFeelPackage;
}
// Desktop corona handler
#include "moc_shellcorona.cpp"

View File

@ -1,159 +0,0 @@
/*
* Copyright 2008 Aaron Seigo <aseigo@kde.org>
* Copyright 2013 Sebastian Kügler <sebas@kde.org>
* Copyright 2013 Ivan Cukic <ivan.cukic@kde.org>
* Copyright 2013 Marco Martin <mart@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library 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 SHELLCORONA_H
#define SHELLCORONA_H
#include "plasma/corona.h"
#include <Plasma/Package>
namespace Plasma
{
class Applet;
} // namespace Plasma
class Activity;
class PanelView;
class QScreen;
namespace WorkspaceScripting {
class DesktopScriptEngine;
}
namespace KActivities {
class Controller;
}
class ShellCorona : public Plasma::Corona
{
Q_OBJECT
Q_PROPERTY(QString shell READ shell WRITE setShell)
Q_CLASSINFO("D-Bus Interface", "org.kde.PlasmaShell")
public:
explicit ShellCorona(QObject * parent = 0);
~ShellCorona();
/**
* Where to save global configuration that doesn't have anything to do with the scene (e.g. views)
*/
KSharedConfig::Ptr applicationConfig();
WorkspaceScripting::DesktopScriptEngine * scriptEngine() const;
int numScreens() const;
QRect screenGeometry(int id) const;
QRegion availableScreenRegion(int id) const;
QRect availableScreenRect(int id) const;
PanelView *panelView(Plasma::Containment *containment) const;
KActivities::Controller *activityController();
Plasma::Package lookAndFeelPackage() const;
//Those two are a bit of an hack but are just for desktop scripting
Activity *activity(const QString &id);
void insertActivity(const QString &id, Activity *activity);
public Q_SLOTS:
/**
* Request saving applicationConfig on disk, it's event compressed, not immediate
*/
void requestApplicationConfigSync();
/**
* Sets the shell that the corona should display
*/
void setShell(const QString & shell);
/**
* Gets the currently shown shell
*/
QString shell() const;
///DBUS methods
void toggleDashboard();
void setDashboardShown(bool show);
void showInteractiveConsole();
void loadScriptInInteractiveConsole(const QString &script);
protected Q_SLOTS:
void screenAdded(QScreen *screen);
void screenRemoved(QObject *screen);
/**
* Loads the layout and performs the needed checks
*/
void load();
/**
* Unloads everything
*/
void unload();
/**
* Loads the default (system wide) layout for this user
**/
void loadDefaultLayout();
/**
* Execute any update script
*/
void processUpdateScripts();
int screenForContainment(const Plasma::Containment *containment) const;
private Q_SLOTS:
void createWaitingPanels();
void handleContainmentAdded(Plasma::Containment *c);
void toggleWidgetExplorer();
void toggleActivityManager();
void syncAppConfig();
void checkActivities();
void currentActivityChanged(const QString &newActivity);
void activityAdded(const QString &id);
void activityRemoved(const QString &id);
void checkAddPanelAction(const QStringList &sycocaChanges = QStringList());
void addPanel();
void addPanel(QAction *action);
void addPanel(const QString &plugin);
void activityOpened();
void activityClosed();
void activityRemoved();
private:
/**
* @returns a new containment associated with the specified @p activity and @p screen.
*/
Plasma::Containment* createContainmentForActivity(const QString& activity, int screenNum);
void insertContainment(const QString &activity, int screenNum, Plasma::Containment *containment);
class Private;
const QScopedPointer<Private> d;
};
#endif // SHELLCORONA_H

View File

@ -1,253 +0,0 @@
/*
* Copyright (C) 2013 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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 "shellmanager.h"
#include <algorithm>
#include <QDebug>
#include <QDir>
#include <QList>
#include <QTimer>
#include <qplatformdefs.h>
#include <QQmlEngine>
#include <QQmlComponent>
#include <config-prefix.h>
#include "shellcorona.h"
#include <kcrash.h>
static const QString s_shellsDir = QString(QStandardPaths::locate(QStandardPaths::QStandardPaths::GenericDataLocation,
"plasma/shells/",
QStandardPaths::LocateDirectory));
static const QString s_shellLoaderPath = QString("/contents/loader.qml");
bool ShellManager::s_forceWindowed = false;
bool ShellManager::s_noRespawn = false;
int ShellManager::crashes = 0;
//
// ShellManager
//
class ShellManager::Private {
public:
Private()
: currentHandler(nullptr)
{
shellUpdateDelay.setInterval(100);
shellUpdateDelay.setSingleShot(true);
}
QList<QObject *> handlers;
QObject * currentHandler;
QTimer shellUpdateDelay;
ShellCorona * corona;
};
ShellManager::ShellManager()
: d(new Private())
{
// Using setCrashHandler, we end up in an infinite loop instead of quitting,
// use setEmergencySaveFunction instead to avoid this.
KCrash::setEmergencySaveFunction(ShellManager::crashHandler);
QTimer::singleShot(15 * 1000, this, SLOT(resetCrashCount()));
connect(
&d->shellUpdateDelay, &QTimer::timeout,
this, &ShellManager::updateShell
);
d->corona = new ShellCorona(this);
connect(
this, &ShellManager::shellChanged,
d->corona, &ShellCorona::setShell
);
loadHandlers();
}
ShellManager::~ShellManager()
{
// if (d->currentHandler)
// d->currentHandler->unload();
}
void ShellManager::loadHandlers()
{
// TODO: Use corona's qml engine when it switches from QScriptEngine
static QQmlEngine * engine = new QQmlEngine(this);
for (const auto & dir: QDir(s_shellsDir).entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
const QString qmlFile = s_shellsDir + dir + s_shellLoaderPath;
// qDebug() << "Making a new instance of " << qmlFile;
QQmlComponent handlerComponent(engine,
QUrl::fromLocalFile(qmlFile)
);
auto handler = handlerComponent.create();
// Writing out the errors
for (const auto & error: handlerComponent.errors()) {
qWarning() << "Error: " << error;
}
if (handler) {
registerHandler(handler);
}
}
updateShell();
}
void ShellManager::registerHandler(QObject * handler)
{
// qDebug() << "We got the handler: " << handler->property("shell").toString();
connect(
handler, &QObject::destroyed,
this, &ShellManager::deregisterHandler
);
connect(
handler, SIGNAL(willingChanged()),
this, SLOT(requestShellUpdate())
);
connect(
handler, SIGNAL(priorityChanged()),
this, SLOT(requestShellUpdate())
);
d->handlers.push_back(handler);
}
void ShellManager::deregisterHandler(QObject * handler)
{
if (d->handlers.contains(handler)) {
d->handlers.removeAll(handler);
handler->disconnect(this);
}
if (d->currentHandler == handler) {
d->currentHandler = nullptr;
updateShell();
}
}
void ShellManager::requestShellUpdate()
{
d->shellUpdateDelay.start();
}
void ShellManager::updateShell()
{
d->shellUpdateDelay.stop();
if (d->handlers.isEmpty()) {
qFatal("We have no shell handlers installed");
return;
}
// Finding the handler that has the priority closest to zero.
// We will return a handler even if there are no willing ones.
auto handler =* std::min_element(d->handlers.cbegin(), d->handlers.cend(),
[] (QObject * left, QObject * right)
{
auto willing = [] (QObject * handler)
{
return handler->property("willing").toBool();
};
auto priority = [] (QObject * handler)
{
return handler->property("priority").toInt();
};
return
// If one is willing and the other is not,
// return it - it has the priority
willing(left) && !willing(right) ? true :
!willing(left) && willing(right) ? false :
// otherwise just compare the priorities
priority(left) < priority(right);
}
);
if (handler == d->currentHandler) return;
// Activating the new handler and killing the old one
if (d->currentHandler) {
d->currentHandler->setProperty("loaded", false);
}
d->currentHandler = handler;
d->currentHandler->setProperty("loaded", true);
emit shellChanged(d->currentHandler->property("shell").toString());
}
ShellManager * ShellManager::instance()
{
static ShellManager manager;
return &manager;
}
void ShellManager::setCrashCount(int count)
{
crashes = count;
}
void ShellManager::resetCrashCount()
{
crashes = 0;
}
void ShellManager::crashHandler(int signal)
{
/* plasma-shell restart logic as crash recovery
*
* We restart plasma-shell after crashes. When it crashes subsequently on startup,
* and more than two times in a row, we give up in order to not endlessly loop.
* Once the shell process stays alive for at least 15 seconds, we reset the crash
* counter, so a later crash, at runtime rather than on startup will still be
* recovered from.
*
* This logic is very similar as to how kwin handles it.
*/
crashes++;
fprintf(stderr, "Application::crashHandler() called with signal %d; recent crashes: %d\n", signal, crashes);
char cmd[1024];
sprintf(cmd, "%s --crashes %d &",
QFile::encodeName(QCoreApplication::applicationFilePath()).constData(), crashes);
if (crashes < 3 && !s_noRespawn) {
sleep(1);
system(cmd);
} else {
fprintf(stderr, "Too many crashes in short order or respawning disabled, not restarting automatically.\n");
}
}

View File

@ -1,73 +0,0 @@
/*
* Copyright (C) 2013 Ivan Cukic <ivan.cukic(at)kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* or (at your option) any later version, as published by the Free
* Software Foundation
*
* 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 SHELLMANAGER_H
#define SHELLMANAGER_H
#include <QObject>
/**
* ShellManager creates a ShellCorona instance and manages it.
*
* Shell manager loads "handlers" from QML files which suggests which shell
* corona should currently be active.
* For example switching between tablet and desktop shells on hardware changes.
*
* This class also provides crash handling.
*/
class ShellManager: public QObject {
Q_OBJECT
public:
static ShellManager * instance();
~ShellManager();
void loadHandlers();
static bool s_forceWindowed;
static bool s_noRespawn;
static void setCrashCount(int count);
protected Q_SLOTS:
void registerHandler(QObject * handler);
void deregisterHandler(QObject * handler);
public Q_SLOTS:
void requestShellUpdate();
void updateShell();
Q_SIGNALS:
void shellChanged(const QString & shell);
private Q_SLOTS:
void resetCrashCount();
private:
ShellManager();
class Private;
const QScopedPointer<Private> d;
static int crashes;
static void crashHandler(int signal);
};
#endif /* SHELLMANAGER_H */

View File

@ -1,27 +0,0 @@
project(plasmawidgetexplorerplugin)
set(widgetexplorer_SRC
kcategorizeditemsviewmodels.cpp
plasmaappletitemmodel.cpp
widgetexplorer.cpp
widgetexplorerplugin.cpp
)
add_library(plasmawidgetexplorerplugin SHARED ${widgetexplorer_SRC})
target_link_libraries(plasmawidgetexplorerplugin
Qt5::Core
Qt5::Quick
Qt5::Qml
Qt5::Gui
Qt5::Widgets
Qt5::Quick
Qt5::Qml
KF5::Plasma
KF5::PlasmaQuick
KF5::I18n
KF5::Service
)
install(TARGETS plasmawidgetexplorerplugin DESTINATION ${QML_INSTALL_DIR}/org/kde/plasma/private/shell)
install(FILES qmldir DESTINATION ${QML_INSTALL_DIR}/org/kde/plasma/private/shell)

View File

@ -1,249 +0,0 @@
/*
* Copyright (C) 2007 Ivan Cukic <ivan.cukic+kde@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library/Lesser General Public License
* version 2, or (at your option) any later version, as published by the
* Free Software Foundation
*
* 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 Library/Lesser 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 "kcategorizeditemsviewmodels_p.h"
#include <klocalizedstring.h>
#define COLUMN_COUNT 4
namespace KCategorizedItemsViewModels {
// AbstractItem
QString AbstractItem::name() const
{
return text();
}
QString AbstractItem::id() const
{
QString plugin = data().toMap()["pluginName"].toString();
if (plugin.isEmpty()) {
return name();
}
return plugin;
}
QString AbstractItem::description() const
{
return "";
}
bool AbstractItem::isFavorite() const
{
return passesFiltering(Filter("favorite", true));
}
int AbstractItem::running() const
{
return 0;
}
bool AbstractItem::matches(const QString &pattern) const
{
return
name().contains(pattern, Qt::CaseInsensitive) ||
description().contains(pattern, Qt::CaseInsensitive);
}
// DefaultFilterModel
DefaultFilterModel::DefaultFilterModel(QObject *parent) :
QStandardItemModel(0, 1, parent)
{
setHeaderData(1, Qt::Horizontal, i18n("Filters"));
//This is to make QML that is understand it
QHash<int, QByteArray> newRoleNames = roleNames();
newRoleNames[FilterTypeRole] = "filterType";
newRoleNames[FilterDataRole] = "filterData";
newRoleNames[SeparatorRole] = "separator";
setRoleNames(newRoleNames);
connect(this, SIGNAL(modelReset()),
this, SIGNAL(countChanged()));
connect(this, SIGNAL(rowsInserted(QModelIndex, int, int)),
this, SIGNAL(countChanged()));
connect(this, SIGNAL(rowsRemoved(QModelIndex, int, int)),
this, SIGNAL(countChanged()));
}
void DefaultFilterModel::addFilter(const QString &caption, const Filter &filter, const QIcon &icon)
{
QList<QStandardItem *> newRow;
QStandardItem *item = new QStandardItem(caption);
item->setData(qVariantFromValue<Filter>(filter));
if (!icon.isNull()) {
item->setIcon(icon);
}
item->setData(filter.first, FilterTypeRole);
item->setData(filter.second, FilterDataRole);
newRow << item;
appendRow(newRow);
}
void DefaultFilterModel::addSeparator(const QString &caption)
{
QList<QStandardItem *> newRow;
QStandardItem *item = new QStandardItem(caption);
item->setEnabled(false);
item->setData(true, SeparatorRole);
newRow << item;
appendRow(newRow);
}
QVariantHash DefaultFilterModel::get(int row) const
{
QModelIndex idx = index(row, 0);
QVariantHash hash;
QHash<int, QByteArray>::const_iterator i;
for (i = roleNames().constBegin(); i != roleNames().constEnd(); ++i) {
hash[i.value()] = data(idx, i.key());
}
return hash;
}
// DefaultItemFilterProxyModel
DefaultItemFilterProxyModel::DefaultItemFilterProxyModel(QObject *parent)
: QSortFilterProxyModel(parent)
{
}
void DefaultItemFilterProxyModel::setSourceModel(QAbstractItemModel *sourceModel)
{
QStandardItemModel *model = qobject_cast<QStandardItemModel*>(sourceModel);
if (!model) {
qWarning() << "Expecting a QStandardItemModel!";
return;
}
setRoleNames(sourceModel->roleNames());
QSortFilterProxyModel::setSourceModel(model);
connect(this, SIGNAL(modelReset()),
this, SIGNAL(countChanged()));
connect(this, SIGNAL(rowsInserted(QModelIndex, int, int)),
this, SIGNAL(countChanged()));
connect(this, SIGNAL(rowsRemoved(QModelIndex, int, int)),
this, SIGNAL(countChanged()));
}
QAbstractItemModel *DefaultItemFilterProxyModel::sourceModel() const
{
return QSortFilterProxyModel::sourceModel();
}
int DefaultItemFilterProxyModel::columnCount(const QModelIndex &index) const
{
Q_UNUSED(index);
return COLUMN_COUNT;
}
QVariant DefaultItemFilterProxyModel::data(const QModelIndex &index, int role) const
{
return QSortFilterProxyModel::data(index, role);
}
bool DefaultItemFilterProxyModel::filterAcceptsRow(int sourceRow,
const QModelIndex &sourceParent) const
{
QStandardItemModel *model = (QStandardItemModel *) sourceModel();
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
AbstractItem *item = (AbstractItem *) model->itemFromIndex(index);
//qDebug() << "ITEM " << (item ? "IS NOT " : "IS") << " NULL\n";
return item &&
(m_filter.first.isEmpty() || item->passesFiltering(m_filter)) &&
(m_searchPattern.isEmpty() || item->matches(m_searchPattern));
}
QVariantHash DefaultItemFilterProxyModel::get(int row) const
{
QModelIndex idx = index(row, 0);
QVariantHash hash;
QHash<int, QByteArray>::const_iterator i;
for (i = roleNames().constBegin(); i != roleNames().constEnd(); ++i) {
hash[i.value()] = data(idx, i.key());
}
return hash;
}
bool DefaultItemFilterProxyModel::lessThan(const QModelIndex &left,
const QModelIndex &right) const
{
return
sourceModel()->data(left).toString().localeAwareCompare(
sourceModel()->data(right).toString()) < 0;
}
void DefaultItemFilterProxyModel::setSearchTerm(const QString &pattern)
{
m_searchPattern = pattern;
invalidateFilter();
emit searchTermChanged(pattern);
}
QString DefaultItemFilterProxyModel::searchTerm() const
{
return m_searchPattern;
}
void DefaultItemFilterProxyModel::setFilter(const Filter &filter)
{
m_filter = filter;
invalidateFilter();
emit filterChanged();
}
void DefaultItemFilterProxyModel::setFilterType(const QString type)
{
m_filter.first = type;
invalidateFilter();
emit filterChanged();
}
QString DefaultItemFilterProxyModel::filterType() const
{
return m_filter.first;
}
void DefaultItemFilterProxyModel::setFilterQuery(const QVariant query)
{
m_filter.second = query;
invalidateFilter();
emit filterChanged();
}
QVariant DefaultItemFilterProxyModel::filterQuery() const
{
return m_filter.second;
}
}

View File

@ -1,177 +0,0 @@
/*
* Copyright (C) 2007 Ivan Cukic <ivan.cukic+kde@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library/Lesser General Public License
* version 2, or (at your option) any later version, as published by the
* Free Software Foundation
*
* 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 Library/Lesser 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 PLASMA_KCATEGORIZEDITEMSVIEWMODELS_P_H
#define PLASMA_KCATEGORIZEDITEMSVIEWMODELS_P_H
#include <QtGui/QtGui>
#include <QtCore/QtCore>
#include <QIcon>
namespace KCategorizedItemsViewModels {
typedef QPair<QString, QVariant> Filter;
/**
* Abstract class that needs to be implemented and used with the ItemModel
*/
class AbstractItem : public QStandardItem
{
public:
/**
* Returns a localized string - name of the item
*/
virtual QString name() const;
/**
* Returns a unique id related to this item
*/
virtual QString id() const;
/**
* Returns a localized string - description of the item
*/
virtual QString description() const;
/**
* Returns if the item is flagged as favorite
* Default implementation checks if the item passes the Filter("favorite", "1") filter
*/
virtual bool isFavorite() const;
/**
* Returns the item's number of running applets
* Default implementation just returns 0
*/
virtual int running() const;
/**
* Returns if the item contains string specified by pattern.
* Default implementation checks whether name or description contain the
* string (not needed to be exactly that string)
*/
virtual bool matches(const QString &pattern) const;
/**
* sets the favorite flag for the item
*/
virtual void setFavorite(bool favorite) = 0;
/**
* sets the number of running applets for the item
*/
virtual void setRunning(int count) = 0;
/**
* Returns if the item passes the filter specified
*/
virtual bool passesFiltering(const Filter &filter) const = 0;
private:
};
/**
* The default implementation of the model containing filters
*/
class DefaultFilterModel : public QStandardItemModel
{
Q_OBJECT
Q_PROPERTY(int count READ count NOTIFY countChanged)
public:
enum Roles {
FilterTypeRole = Qt::UserRole+1,
FilterDataRole = Qt::UserRole+2,
SeparatorRole = Qt::UserRole+3
};
DefaultFilterModel(QObject *parent = 0);
/**
* Adds a filter to the model
* @param caption The localized string to be displayed as a name of the filter
* @param filter The filter structure
*/
void addFilter(const QString &caption, const Filter &filter, const QIcon &icon = QIcon());
/**
* Adds a separator to the model
* @param caption The localized string to be displayed as a name of the separator
*/
void addSeparator(const QString &caption);
int count() {return rowCount(QModelIndex());}
Q_INVOKABLE QVariantHash get(int i) const;
Q_SIGNALS:
void countChanged();
};
/**
* Default filter proxy model.
*/
class DefaultItemFilterProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
Q_PROPERTY(QString searchTerm READ searchTerm WRITE setSearchTerm NOTIFY searchTermChanged)
Q_PROPERTY(QString filterType READ filterType WRITE setFilterType NOTIFY filterChanged)
Q_PROPERTY(QVariant filterQuery READ filterQuery WRITE setFilterQuery NOTIFY filterChanged)
Q_PROPERTY(int count READ count NOTIFY countChanged)
public:
DefaultItemFilterProxyModel(QObject *parent = 0);
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
bool lessThan(const QModelIndex &left, const QModelIndex &right) const;
void setSearchTerm(const QString &pattern);
QString searchTerm() const;
void setFilterType(const QString type);
QString filterType() const;
void setFilterQuery(const QVariant query);
QVariant filterQuery() const;
void setFilter(const Filter &filter);
void setSourceModel(QAbstractItemModel *sourceModel);
QAbstractItemModel *sourceModel() const;
int columnCount(const QModelIndex &index) const;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
int count() {return rowCount(QModelIndex());}
Q_INVOKABLE QVariantHash get(int i) const;
Q_SIGNALS:
void searchTermChanged(const QString &term);
void filterChanged();
void countChanged();
private:
Filter m_filter;
QString m_searchPattern;
};
} //end of namespace
Q_DECLARE_METATYPE(KCategorizedItemsViewModels::Filter)
#endif /*KCATEGORIZEDITEMSVIEWMODELS_H_*/

View File

@ -1,361 +0,0 @@
/*
* Copyright (C) 2007 Ivan Cukic <ivan.cukic+kde@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library/Lesser General Public License
* version 2, or (at your option) any later version, as published by the
* Free Software Foundation
*
* 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 Library/Lesser 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 "plasmaappletitemmodel_p.h"
#include <QStandardPaths>
#include <QFileInfo>
#include <klocalizedstring.h>
#include <kservicetypetrader.h>
#include <ksycoca.h>
PlasmaAppletItem::PlasmaAppletItem(PlasmaAppletItemModel *model,
const KPluginInfo& info,
FilterFlags flags)
: QObject(model),
m_model(model),
m_info(info),
m_runningCount(0),
m_favorite(flags & Favorite),
m_local(false)
{
const QString api(m_info.property("X-Plasma-API").toString());
if (!api.isEmpty()) {
const QString _f = "plasma/plasmoids/" + info.pluginName() + '/';
QFileInfo dir(QStandardPaths::locate(QStandardPaths::QStandardPaths::GenericDataLocation,
_f,
QStandardPaths::LocateDirectory));
m_local = dir.exists() && dir.isWritable();
}
//attrs.insert("recommended", flags & Recommended ? true : false);
setText(m_info.name() + " - "+ m_info.category().toLower());
const QString iconName = m_info.icon().isEmpty() ? "application-x-plasma" : info.icon();
QIcon icon = QIcon::fromTheme(iconName);
setIcon(icon);
//set plugininfo parts as roles in the model, only way qml can understand it
setData(info.name(), PlasmaAppletItemModel::NameRole);
setData(info.pluginName(), PlasmaAppletItemModel::PluginNameRole);
setData(info.comment(), PlasmaAppletItemModel::DescriptionRole);
setData(info.category().toLower(), PlasmaAppletItemModel::CategoryRole);
setData(info.license(), PlasmaAppletItemModel::LicenseRole);
setData(info.website(), PlasmaAppletItemModel::WebsiteRole);
setData(info.version(), PlasmaAppletItemModel::VersionRole);
setData(info.author(), PlasmaAppletItemModel::AuthorRole);
setData(info.email(), PlasmaAppletItemModel::EmailRole);
setData(0, PlasmaAppletItemModel::RunningRole);
setData(m_local, PlasmaAppletItemModel::LocalRole);
}
QString PlasmaAppletItem::pluginName() const
{
return m_info.pluginName();
}
QString PlasmaAppletItem::name() const
{
return m_info.name();
}
QString PlasmaAppletItem::description() const
{
return m_info.comment();
}
QString PlasmaAppletItem::license() const
{
return m_info.license();
}
QString PlasmaAppletItem::category() const
{
return m_info.category();
}
QString PlasmaAppletItem::website() const
{
return m_info.website();
}
QString PlasmaAppletItem::version() const
{
return m_info.version();
}
QString PlasmaAppletItem::author() const
{
return m_info.author();
}
QString PlasmaAppletItem::email() const
{
return m_info.email();
}
int PlasmaAppletItem::running() const
{
return m_runningCount;
}
void PlasmaAppletItem::setRunning(int count)
{
m_runningCount = count;
setData(count, PlasmaAppletItemModel::RunningRole);
emitDataChanged();
}
bool PlasmaAppletItem::matches(const QString &pattern) const
{
if (m_info.service()) {
const QStringList keywords = m_info.property("Keywords").toStringList();
foreach (const QString &keyword, keywords) {
if (keyword.startsWith(pattern, Qt::CaseInsensitive)) {
return true;
}
}
}
return AbstractItem::matches(pattern);
}
bool PlasmaAppletItem::isFavorite() const
{
return m_favorite;
}
void PlasmaAppletItem::setFavorite(bool favorite)
{
if (m_favorite != favorite) {
m_favorite = favorite;
m_model->setFavorite(m_info.pluginName(), favorite);
emitDataChanged();
}
}
bool PlasmaAppletItem::isLocal() const
{
return m_local;
}
bool PlasmaAppletItem::passesFiltering(const KCategorizedItemsViewModels::Filter &filter) const
{
if (filter.first == "running") {
return running();
} else if (filter.first == "category") {
return m_info.category().toLower() == filter.second;
} else {
return false;
}
}
QMimeData *PlasmaAppletItem::mimeData() const
{
QMimeData *data = new QMimeData();
QByteArray appletName;
appletName += pluginName().toUtf8();
data->setData(mimeTypes().at(0), appletName);
return data;
}
QStringList PlasmaAppletItem::mimeTypes() const
{
QStringList types;
types << QLatin1String("text/x-plasmoidservicename");
return types;
}
PlasmaAppletItemModel* PlasmaAppletItem::appletItemModel()
{
return m_model;
}
//PlasmaAppletItemModel
PlasmaAppletItemModel::PlasmaAppletItemModel(QObject * parent)
: QStandardItemModel(parent)
{
KConfig config("plasmarc");
m_configGroup = KConfigGroup(&config, "Applet Browser");
m_favorites = m_configGroup.readEntry("favorites").split(',');
connect(KSycoca::self(), SIGNAL(databaseChanged(QStringList)), this, SLOT(populateModel(QStringList)));
//This is to make QML that is understand it
QHash<int, QByteArray> newRoleNames = roleNames();
newRoleNames[NameRole] = "name";
newRoleNames[PluginNameRole] = "pluginName";
newRoleNames[DescriptionRole] = "description";
newRoleNames[CategoryRole] = "category";
newRoleNames[LicenseRole] = "license";
newRoleNames[WebsiteRole] = "website";
newRoleNames[VersionRole] = "version";
newRoleNames[AuthorRole] = "author";
newRoleNames[EmailRole] = "email";
newRoleNames[RunningRole] = "running";
newRoleNames[LocalRole] = "local";
setRoleNames(newRoleNames);
setSortRole(Qt::DisplayRole);
}
void PlasmaAppletItemModel::populateModel(const QStringList &whatChanged)
{
if (!whatChanged.isEmpty() && !whatChanged.contains("services")) {
return;
}
clear();
//qDebug() << "populating model, our application is" << m_application;
//qDebug() << "number of applets is"
// << Plasma::Applet::listAppletInfo(QString(), m_application).count();
KService::List services = KServiceTypeTrader::self()->query("Plasma/Applet", QString());
foreach (const QExplicitlySharedDataPointer<KService> service, services) {
KPluginInfo info(service);
//qDebug() << info.pluginName() << "NoDisplay" << info.property("NoDisplay").toBool();
if (info.property("NoDisplay").toBool() || info.category() == i18n("Containments")) {
// we don't want to show the hidden category
continue;
}
qDebug() << info.pluginName() << " is the name of the plugin at" << info.entryPath();
//qDebug() << info.name() << info.property("X-Plasma-Thumbnail");
PlasmaAppletItem::FilterFlags flags(PlasmaAppletItem::NoFilter);
if (m_favorites.contains(info.pluginName())) {
flags |= PlasmaAppletItem::Favorite;
}
appendRow(new PlasmaAppletItem(this, info, flags));
}
emit modelPopulated();
}
void PlasmaAppletItemModel::setRunningApplets(const QHash<QString, int> &apps)
{
//foreach item, find that string and set the count
for (int r = 0; r < rowCount(); ++r) {
QStandardItem *i = item(r);
PlasmaAppletItem *p = dynamic_cast<PlasmaAppletItem *>(i);
if (p) {
const bool running = apps.value(p->pluginName());
p->setRunning(running);
}
}
}
void PlasmaAppletItemModel::setRunningApplets(const QString &name, int count)
{
for (int r=0; r<rowCount(); ++r) {
QStandardItem *i = item(r);
PlasmaAppletItem *p = dynamic_cast<PlasmaAppletItem *>(i);
if (p && p->pluginName() == name) {
p->setRunning(count);
}
}
}
QStringList PlasmaAppletItemModel::mimeTypes() const
{
QStringList types;
types << QLatin1String("text/x-plasmoidservicename");
return types;
}
QSet<QString> PlasmaAppletItemModel::categories() const
{
QSet<QString> cats;
for (int r = 0; r < rowCount(); ++r) {
QStandardItem *i = item(r);
PlasmaAppletItem *p = dynamic_cast<PlasmaAppletItem *>(i);
if (p) {
cats.insert(p->category().toLower());
}
}
return cats;
}
QMimeData *PlasmaAppletItemModel::mimeData(const QModelIndexList &indexes) const
{
//qDebug() << "GETTING MIME DATA\n";
if (indexes.count() <= 0) {
return 0;
}
QStringList types = mimeTypes();
if (types.isEmpty()) {
return 0;
}
QMimeData *data = new QMimeData();
QString format = types.at(0);
QByteArray appletNames;
int lastRow = -1;
foreach (const QModelIndex &index, indexes) {
if (index.row() == lastRow) {
continue;
}
lastRow = index.row();
PlasmaAppletItem *selectedItem = (PlasmaAppletItem *) itemFromIndex(index);
appletNames += '\n' + selectedItem->pluginName().toUtf8();
//qDebug() << selectedItem->pluginName() << index.column() << index.row();
}
data->setData(format, appletNames);
return data;
}
void PlasmaAppletItemModel::setFavorite(const QString &plugin, bool favorite)
{
if (favorite) {
if (!m_favorites.contains(plugin)) {
m_favorites.append(plugin);
}
} else {
m_favorites.removeAll(plugin);
}
m_configGroup.writeEntry("favorites", m_favorites.join(","));
m_configGroup.sync();
}
void PlasmaAppletItemModel::setApplication(const QString &app)
{
m_application = app;
populateModel();
}
QString &PlasmaAppletItemModel::Application()
{
return m_application;
}
//#include <plasmaappletitemmodel_p.moc>

View File

@ -1,124 +0,0 @@
/*
* Copyright (C) 2007 Ivan Cukic <ivan.cukic+kde@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library/Lesser General Public License
* version 2, or (at your option) any later version, as published by the
* Free Software Foundation
*
* 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 Library/Lesser 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 PLASMA_PLASMAAPPLETITEMMODEL_P_H
#define PLASMA_PLASMAAPPLETITEMMODEL_P_H
#include <kplugininfo.h>
#include <Plasma/Applet>
#include "kcategorizeditemsviewmodels_p.h"
class PlasmaAppletItemModel;
/**
* Implementation of the KCategorizedItemsViewModels::AbstractItem
*/
class PlasmaAppletItem : public QObject, public KCategorizedItemsViewModels::AbstractItem
{
Q_OBJECT
public:
enum FilterFlag {
NoFilter = 0,
Favorite = 1
};
Q_DECLARE_FLAGS(FilterFlags, FilterFlag)
PlasmaAppletItem(PlasmaAppletItemModel *model, const KPluginInfo& info, FilterFlags flags = NoFilter);
QString pluginName() const;
QString name() const;
QString category() const;
QString description() const;
QString license() const;
QString website() const;
QString version() const;
QString author() const;
QString email() const;
int running() const;
bool isLocal() const;
bool isFavorite() const;
void setFavorite(bool favorite);
PlasmaAppletItemModel* appletItemModel();
bool matches(const QString &pattern) const;
//set how many instances of this applet are running
void setRunning(int count);
bool passesFiltering(const KCategorizedItemsViewModels::Filter & filter) const;
QMimeData *mimeData() const;
QStringList mimeTypes() const;
private:
PlasmaAppletItemModel * m_model;
KPluginInfo m_info;
int m_runningCount;
bool m_favorite;
bool m_local;
};
class PlasmaAppletItemModel : public QStandardItemModel
{
Q_OBJECT
public:
enum Roles {
NameRole = Qt::UserRole+1,
PluginNameRole = Qt::UserRole+2,
DescriptionRole = Qt::UserRole+3,
CategoryRole = Qt::UserRole+4,
LicenseRole = Qt::UserRole+5,
WebsiteRole = Qt::UserRole+6,
VersionRole = Qt::UserRole+7,
AuthorRole = Qt::UserRole+8,
EmailRole = Qt::UserRole+9,
RunningRole = Qt::UserRole+10,
LocalRole = Qt::UserRole+11
};
explicit PlasmaAppletItemModel(QObject * parent = 0);
QStringList mimeTypes() const;
QSet<QString> categories() const;
QMimeData *mimeData(const QModelIndexList &indexes) const;
void setFavorite(const QString &plugin, bool favorite);
void setApplication(const QString &app);
void setRunningApplets(const QHash<QString, int> &apps);
void setRunningApplets(const QString &name, int count);
QString &Application();
Q_SIGNALS:
void modelPopulated();
private:
QString m_application;
QStringList m_favorites;
KConfigGroup m_configGroup;
private Q_SLOTS:
void populateModel(const QStringList &whatChanged = QStringList());
};
Q_DECLARE_OPERATORS_FOR_FLAGS(PlasmaAppletItem::FilterFlags)
#endif /*PLASMAAPPLETSMODEL_H_*/

View File

@ -1,2 +0,0 @@
module org.kde.plasma.private.shell
plugin plasmawidgetexplorerplugin

View File

@ -1,469 +0,0 @@
/*
* Copyright (C) 2007 by Ivan Cukic <ivan.cukic+kde@gmail.com>
* Copyright (C) 2009 by Ana Cecília Martins <anaceciliamb@gmail.com>
* Copyright 2013 by Sebastian Kügler <sebas@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library/Lesser General Public License
* version 2, or (at your option) any later version, as published by the
* Free Software Foundation
*
* 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 Library/Lesser 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 "widgetexplorer.h"
#include <QQmlEngine>
#include <QQmlContext>
#include <QQmlExpression>
#include <QQmlProperty>
#include <klocalizedstring.h>
#include <kservicetypetrader.h>
#include <Plasma/Applet>
#include <Plasma/Corona>
#include <Plasma/Containment>
#include <Plasma/Package>
#include <Plasma/PackageStructure>
#include <qstandardpaths.h>
#include <view.h>
#include "kcategorizeditemsviewmodels_p.h"
#include "plasmaappletitemmodel_p.h"
using namespace KCategorizedItemsViewModels;
using namespace Plasma;
WidgetAction::WidgetAction(QObject *parent)
: QAction(parent)
{
}
WidgetAction::WidgetAction(const QIcon &icon, const QString &text, QObject *parent)
: QAction(icon, text, parent)
{
}
class WidgetExplorerPrivate
{
public:
WidgetExplorerPrivate(WidgetExplorer *w)
: q(w),
containment(0),
itemModel(w),
filterModel(w),
view(0)
{
}
void initFilters();
void initRunningApplets();
void containmentDestroyed();
/**
* Tracks a new running applet
*/
void appletAdded(Plasma::Applet *applet);
/**
* A running applet is no more
*/
void appletRemoved(Plasma::Applet *applet);
WidgetExplorer *q;
QString application;
Plasma::Containment *containment;
QHash<QString, int> runningApplets; // applet name => count
//extra hash so we can look up the names of deleted applets
QHash<Plasma::Applet *,QString> appletNames;
//QWeakPointer<Plasma::OpenWidgetAssistant> openAssistant;
Plasma::Package *package;
PlasmaAppletItemModel itemModel;
KCategorizedItemsViewModels::DefaultFilterModel filterModel;
DefaultItemFilterProxyModel filterItemModel;
PlasmaQuickView *view;
};
void WidgetExplorerPrivate::initFilters()
{
filterModel.addFilter(i18n("All Widgets"),
KCategorizedItemsViewModels::Filter(), QIcon::fromTheme("plasma"));
// Filters: Special
filterModel.addFilter(i18n("Running"),
KCategorizedItemsViewModels::Filter("running", true),
QIcon::fromTheme("dialog-ok"));
filterModel.addSeparator(i18n("Categories:"));
typedef QPair<QString, QString> catPair;
QMap<QString, catPair > categories;
QSet<QString> existingCategories = itemModel.categories();
//foreach (const QString &category, Plasma::Applet::listCategories(application)) {
QStringList cats;
KService::List services = KServiceTypeTrader::self()->query("Plasma/Applet", QString());
foreach (const QExplicitlySharedDataPointer<KService> service, services) {
KPluginInfo info(service);
if (info.property("NoDisplay").toBool() || info.category() == i18n("Containments") ||
info.category().isEmpty()) {
// we don't want to show the hidden category
continue;
}
const QString c = info.category();
if (-1 == cats.indexOf(c)) {
cats << c;
}
}
qWarning() << "TODO: port listCategories()";
foreach (const QString &category, cats) {
const QString lowerCaseCat = category.toLower();
if (existingCategories.contains(lowerCaseCat)) {
const QString trans = i18n(category.toLocal8Bit());
categories.insert(trans.toLower(), qMakePair(trans, lowerCaseCat));
qDebug() << "Categories: << " << lowerCaseCat;
}
}
foreach (const catPair &category, categories) {
filterModel.addFilter(category.first,
KCategorizedItemsViewModels::Filter("category", category.second));
}
}
QObject *WidgetExplorer::widgetsModel() const
{
return &d->filterItemModel;
}
QObject *WidgetExplorer::filterModel() const
{
return &d->filterModel;
}
QList <QObject *> WidgetExplorer::widgetsMenuActions()
{
QList <QObject *> actionList;
QSignalMapper *mapper = new QSignalMapper(this);
QObject::connect(mapper, SIGNAL(mapped(QString)), this, SLOT(downloadWidgets(QString)));
WidgetAction *action = new WidgetAction(QIcon::fromTheme("applications-internet"),
i18n("Download New Plasma Widgets"), this);
QObject::connect(action, SIGNAL(triggered(bool)), mapper, SLOT(map()));
mapper->setMapping(action, QString());
actionList << action;
KService::List offers = KServiceTypeTrader::self()->query("Plasma/PackageStructure");
foreach (const KService::Ptr &service, offers) {
//qDebug() << service->property("X-Plasma-ProvidesWidgetBrowser");
if (service->property("X-Plasma-ProvidesWidgetBrowser").toBool()) {
WidgetAction *action = new WidgetAction(QIcon::fromTheme("applications-internet"),
i18nc("%1 is a type of widgets, as defined by "
"e.g. some plasma-packagestructure-*.desktop files",
"Download New %1", service->name()), this);
QObject::connect(action, SIGNAL(triggered(bool)), mapper, SLOT(map()));
mapper->setMapping(action, service->property("X-KDE-PluginInfo-Name").toString());
actionList << action;
}
}
action = new WidgetAction(this);
action->setSeparator(true);
actionList << action;
action = new WidgetAction(QIcon::fromTheme("package-x-generic"),
i18n("Install Widget From Local File..."), this);
QObject::connect(action, SIGNAL(triggered(bool)), this, SLOT(openWidgetFile()));
actionList << action;
return actionList;
}
QList<QObject *> WidgetExplorer::extraActions() const
{
QList<QObject *> actionList;
// foreach (QAction *action, actions()) { // FIXME: where did actions() come from?
// actionList << action;
// }
qWarning() << "extraactions needs reimplementation";
return actionList;
}
void WidgetExplorerPrivate::initRunningApplets()
{
//get applets from corona, count them, send results to model
if (!containment) {
return;
}
Plasma::Corona *c = containment->corona();
//we've tried our best to get a corona
//we don't want just one containment, we want them all
if (!c) {
qDebug() << "can't happen";
return;
}
appletNames.clear();
runningApplets.clear();
QList<Containment*> containments = c->containments();
foreach (Containment *containment, containments) {
QObject::connect(containment, SIGNAL(appletAdded(Plasma::Applet*)), q, SLOT(appletAdded(Plasma::Applet*)));
QObject::connect(containment, SIGNAL(appletRemoved(Plasma::Applet*)), q, SLOT(appletRemoved(Plasma::Applet*)));
foreach (Applet *applet, containment->applets()) {
if (applet->pluginInfo().isValid()) {
runningApplets[applet->pluginInfo().pluginName()]++;
} else {
qDebug() << "Invalid plugininfo. :(";
}
}
}
//qDebug() << runningApplets;
itemModel.setRunningApplets(runningApplets);
}
void WidgetExplorerPrivate::containmentDestroyed()
{
containment = 0;
}
void WidgetExplorerPrivate::appletAdded(Plasma::Applet *applet)
{
QString name = applet->pluginInfo().pluginName();
runningApplets[name]++;
appletNames.insert(applet, name);
itemModel.setRunningApplets(name, runningApplets[name]);
}
void WidgetExplorerPrivate::appletRemoved(Plasma::Applet *applet)
{
QString name = appletNames.take(applet);
int count = 0;
if (runningApplets.contains(name)) {
count = runningApplets[name] - 1;
if (count < 1) {
runningApplets.remove(name);
} else {
runningApplets[name] = count;
}
}
itemModel.setRunningApplets(name, count);
}
//WidgetExplorer
WidgetExplorer::WidgetExplorer(QObject *parent)
: QObject(parent),
d(new WidgetExplorerPrivate(this))
{
//FIXME: delay
setApplication();
d->initRunningApplets();
d->filterItemModel.setSortCaseSensitivity(Qt::CaseInsensitive);
d->filterItemModel.setDynamicSortFilter(true);
d->filterItemModel.setSourceModel(&d->itemModel);
d->filterItemModel.sort(0);
}
WidgetExplorer::~WidgetExplorer()
{
delete d;
}
void WidgetExplorer::setApplication(const QString &app)
{
if (d->application == app && !app.isEmpty()) {
return;
}
d->application = app;
d->itemModel.setApplication(app);
d->initFilters();
d->itemModel.setRunningApplets(d->runningApplets);
emit applicationChanged();
}
QString WidgetExplorer::application()
{
return d->application;
}
void WidgetExplorer::setContainment(Plasma::Containment *containment)
{
if (d->containment != containment) {
if (d->containment) {
d->containment->disconnect(this);
}
d->containment = containment;
if (d->containment) {
connect(d->containment, SIGNAL(destroyed(QObject*)), this, SLOT(containmentDestroyed()));
connect(d->containment, SIGNAL(immutabilityChanged(Plasma::Types::ImmutabilityType)), this, SLOT(immutabilityChanged(Plasma::Types::ImmutabilityType)));
}
d->initRunningApplets();
emit containmentChanged();
}
}
Containment *WidgetExplorer::containment() const
{
return d->containment;
}
Plasma::Corona *WidgetExplorer::corona() const
{
if (d->containment) {
return d->containment->corona();
}
return 0;
}
void WidgetExplorer::addApplet(const QString &pluginName)
{
const QString p = "plasma/plasmoids/"+pluginName;
qWarning() << "--------> load applet: " << pluginName << " relpath: " << p;
QStringList dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, p, QStandardPaths::LocateDirectory);
qDebug() << " .. pathes: " << dirs;
if (!dirs.count()) {
qWarning() << "Failed to find plasmoid path for " << pluginName;
return;
}
Plasma::Applet *applet = Plasma::Applet::loadPlasmoid(dirs.first());
if (applet) {
if (d->containment) {
d->containment->addApplet(applet);
} else {
qWarning() << "No containment set (but the applet loaded).";
}
} else {
qWarning() << "Failed to load applet" << pluginName << dirs;
}
}
void WidgetExplorer::immutabilityChanged(Plasma::Types::ImmutabilityType type)
{
if (type != Plasma::Types::Mutable) {
emit shouldClose();
}
}
void WidgetExplorer::downloadWidgets(const QString &type)
{
Plasma::PackageStructure *installer = 0;
if (!type.isEmpty()) {
QString constraint = QString("'%1' == [X-KDE-PluginInfo-Name]").arg(type);
KService::List offers = KServiceTypeTrader::self()->query("Plasma/PackageStructure",
constraint);
if (offers.isEmpty()) {
//qDebug() << "could not find requested PackageStructure plugin" << type;
} else {
KService::Ptr service = offers.first();
QString error;
// FIXME: port install to plasma2
// installer = service->createInstance<Plasma::PackageStructure>(topLevelWidget(),
// QVariantList(), &error);
if (installer) {
// connect(installer, SIGNAL(newWidgetBrowserFinished()),
// installer, SLOT(deleteLater()));
} else {
//qDebug() << "found, but could not load requested PackageStructure plugin" << type
// << "; reported error was" << error;
}
}
}
if (installer) {
//installer->createNewWidgetBrowser();
} else {
// we don't need to delete the default Applet::packageStructure as that
// belongs to the applet
// Plasma::Applet::packageStructure()->createNewWidgetBrowser();
/**
for reference in a libplasma2 world, the above line equates to this:
KNS3::DownloadDialog *knsDialog = m_knsDialog.data();
if (!knsDialog) {
m_knsDialog = knsDialog = new KNS3::DownloadDialog("plasmoids.knsrc", parent);
connect(knsDialog, SIGNAL(accepted()), this, SIGNAL(newWidgetBrowserFinished()));
}
knsDialog->show();
knsDialog->raise();
*/
}
emit shouldClose();
}
void WidgetExplorer::openWidgetFile()
{
/*
Plasma::OpenWidgetAssistant *assistant = d->openAssistant.data();
if (!assistant) {
assistant = new Plasma::OpenWidgetAssistant(0);
d->openAssistant = assistant;
}
KWindowSystem::setOnDesktop(assistant->winId(), KWindowSystem::currentDesktop());
assistant->setAttribute(Qt::WA_DeleteOnClose, true);
assistant->show();
assistant->raise();
assistant->setFocus();
*/
emit shouldClose();
}
void WidgetExplorer::uninstall(const QString &pluginName)
{
const QString packageRoot = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/plasma/plasmoids/";
Plasma::Package pkg;
pkg.setPath(packageRoot);
pkg.uninstall(pluginName, packageRoot);
//FIXME: moreefficient way rather a linear scan?
for (int i = 0; i < d->itemModel.rowCount(); ++i) {
QStandardItem *item = d->itemModel.item(i);
if (item->data(PlasmaAppletItemModel::PluginNameRole).toString() == pluginName) {
d->itemModel.takeRow(i);
break;
}
}
}
#include "moc_widgetexplorer.cpp"

View File

@ -1,156 +0,0 @@
/*
* Copyright (C) 2007 by Ivan Cukic <ivan.cukic+kde@gmail.com>
* Copyright (C) 2009 by Ana Cecília Martins <anaceciliamb@gmail.com>
* Copyright 2013 by Sebastian Kügler <sebas@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library/Lesser General Public License
* version 2, or (at your option) any later version, as published by the
* Free Software Foundation
*
* 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 Library/Lesser 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 WIDGETEXPLORER_H
#define WIDGETEXPLORER_H
#include <QAction>
#include <QObject>
#include "plasmaappletitemmodel_p.h"
namespace Plasma {
class Corona;
class Containment;
class Applet;
}
class WidgetExplorerPrivate;
class PlasmaQuickView;
//We need to access the separator property that is not exported by QAction
class WidgetAction : public QAction
{
Q_OBJECT
Q_PROPERTY(bool separator READ isSeparator WRITE setSeparator NOTIFY separatorChanged)
public:
WidgetAction(QObject *parent = 0);
WidgetAction(const QIcon &icon, const QString &text, QObject *parent);
Q_SIGNALS:
void separatorChanged();
};
class WidgetExplorer : public QObject
{
Q_OBJECT
/**
* Model that lists all applets
*/
Q_PROPERTY(QObject * widgetsModel READ widgetsModel CONSTANT)
/**
* Model that lists all applets filters and categories
*/
Q_PROPERTY(QObject * filterModel READ filterModel CONSTANT)
/**
* Actions for adding widgets, like download plasma widgets, download google gadgets, install from local file
*/
Q_PROPERTY(QList<QObject *> widgetsMenuActions READ widgetsMenuActions NOTIFY widgetsMenuActionsChanged)
/**
* Extra actions assigned by the shell, like switch to activity manager
*/
Q_PROPERTY(QList<QObject *> extraActions READ extraActions NOTIFY extraActionsChanged)
/**
* The application that owns the widget list. different application may show different lists
*/
Q_PROPERTY(QString application READ application WRITE setApplication NOTIFY applicationChanged)
Q_PROPERTY(Plasma::Containment *containment READ containment WRITE setContainment NOTIFY containmentChanged)
public:
explicit WidgetExplorer(QObject *parent = 0);
~WidgetExplorer();
QString application();
/**
* Populates the widget list for the given application. This must be called
* before the widget explorer will be usable as the widget list will remain
* empty up to that point.
*
* @arg application the application which the widgets should be loaded for.
*/
void setApplication(const QString &application = QString());
/**
* Changes the current default containment to add applets to
*
* @arg containment the new default
*/
void setContainment(Plasma::Containment *containment);
/**
* @return the current default containment to add applets to
*/
Plasma::Containment *containment() const;
/**
* @return the current corona this widget is added to
*/
Plasma::Corona *corona() const;
QObject *widgetsModel() const;
QObject *filterModel() const;
QList <QObject *> widgetsMenuActions();
QList <QObject *> extraActions() const;
/**
* Uninstall a plasmoid with a given plugin name. only user-installed ones are uninstallable
*/
Q_INVOKABLE void uninstall(const QString &pluginName);
Q_SIGNALS:
void widgetsMenuActionsChanged();
void extraActionsChanged();
void shouldClose();
void viewChanged();
void applicationChanged();
void containmentChanged();
public Q_SLOTS:
/**
* Adds currently selected applets
*/
void addApplet(const QString &pluginName);
void openWidgetFile();
void downloadWidgets(const QString &type);
protected Q_SLOTS:
void immutabilityChanged(Plasma::Types::ImmutabilityType);
private:
Q_PRIVATE_SLOT(d, void appletAdded(Plasma::Applet*))
Q_PRIVATE_SLOT(d, void appletRemoved(Plasma::Applet*))
Q_PRIVATE_SLOT(d, void containmentDestroyed())
WidgetExplorerPrivate * const d;
friend class WidgetExplorerPrivate;
};
#endif // WIDGETEXPLORER_H

View File

@ -1,36 +0,0 @@
/*
Copyright 2014 by David Edmundson <davidedmundson@kde.org>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "widgetexplorerplugin.h"
#include <QtQml>
#include "widgetexplorer.h"
#include <plasma/containment.h>
void WidgetExplorerPlugin::registerTypes(const char *uri)
{
Q_ASSERT(uri == QLatin1String("org.kde.plasma.private.shell"));
qmlRegisterType<Plasma::Containment>();
qmlRegisterType<WidgetExplorer>(uri, 2, 0, "WidgetExplorer");
}

View File

@ -1,37 +0,0 @@
/*
Copyright 2014 by David Edmundson <davidedmundson@kde.org>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef WIDGETEXPLORERPLUGIN_H
#define WIDGETEXPLORERPLUGIN_H
#include <QQmlExtensionPlugin>
class WidgetExplorerPlugin : public QQmlExtensionPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
public:
void registerTypes(const char *uri);
};
#endif