From 2ad2d65ed8079469bf0cd782ae27a70e85e8eddd Mon Sep 17 00:00:00 2001 From: Ryan James Rix Date: Sat, 4 Sep 2010 23:23:35 +0000 Subject: [PATCH] Move plasma-kpart to kdebase-runtime. FEATURE: New kpart to aide development of application dashboards svn path=/trunk/KDE/kdebase/runtime/; revision=1171736 --- kpart/CMakeLists.txt | 33 ++ kpart/README | 7 + kpart/kpart.kdev4 | 3 + kpart/plasma-kpart.desktop | 12 + kpart/plasmakpart.cpp | 185 +++++++++ kpart/plasmakpart.h | 117 ++++++ kpart/plasmakpartcorona.cpp | 94 +++++ kpart/plasmakpartcorona.h | 57 +++ kpart/plasmakpartview.cpp | 85 ++++ kpart/plasmakpartview.h | 64 +++ kpart/scripting/backportglobal.h | 364 +++++++++++++++++ .../layouttemplatepackagestructure.cpp | 42 ++ .../layouttemplatepackagestructure.h | 40 ++ kpart/scripting/rect.cpp | 327 +++++++++++++++ kpart/scripting/scriptengine.cpp | 374 ++++++++++++++++++ kpart/scripting/scriptengine.h | 81 ++++ kpart/scripting/widget.cpp | 275 +++++++++++++ kpart/scripting/widget.h | 98 +++++ kpart/shell/CMakeLists.txt | 17 + kpart/shell/appletselector.cpp | 67 ++++ kpart/shell/appletselector.h | 44 +++ kpart/shell/appletselector.ui | 44 +++ kpart/shell/containmentshell.cpp | 109 +++++ kpart/shell/containmentshell.h | 51 +++ kpart/shell/main.cpp | 44 +++ kpart/shell/plasma-default-layoutrc | 61 +++ kpart/shell/plasma-kpart-shell.desktop | 22 ++ kpart/shell/plasma-kpart-shellui.rc | 31 ++ kpart/shell/testshellpluginloader.cpp | 49 +++ kpart/shell/testshellpluginloader.h | 35 ++ 30 files changed, 2832 insertions(+) create mode 100644 kpart/CMakeLists.txt create mode 100644 kpart/README create mode 100644 kpart/kpart.kdev4 create mode 100644 kpart/plasma-kpart.desktop create mode 100644 kpart/plasmakpart.cpp create mode 100644 kpart/plasmakpart.h create mode 100644 kpart/plasmakpartcorona.cpp create mode 100644 kpart/plasmakpartcorona.h create mode 100644 kpart/plasmakpartview.cpp create mode 100644 kpart/plasmakpartview.h create mode 100644 kpart/scripting/backportglobal.h create mode 100644 kpart/scripting/layouttemplatepackagestructure.cpp create mode 100644 kpart/scripting/layouttemplatepackagestructure.h create mode 100644 kpart/scripting/rect.cpp create mode 100644 kpart/scripting/scriptengine.cpp create mode 100644 kpart/scripting/scriptengine.h create mode 100644 kpart/scripting/widget.cpp create mode 100644 kpart/scripting/widget.h create mode 100644 kpart/shell/CMakeLists.txt create mode 100644 kpart/shell/appletselector.cpp create mode 100644 kpart/shell/appletselector.h create mode 100644 kpart/shell/appletselector.ui create mode 100644 kpart/shell/containmentshell.cpp create mode 100644 kpart/shell/containmentshell.h create mode 100644 kpart/shell/main.cpp create mode 100644 kpart/shell/plasma-default-layoutrc create mode 100644 kpart/shell/plasma-kpart-shell.desktop create mode 100644 kpart/shell/plasma-kpart-shellui.rc create mode 100644 kpart/shell/testshellpluginloader.cpp create mode 100644 kpart/shell/testshellpluginloader.h diff --git a/kpart/CMakeLists.txt b/kpart/CMakeLists.txt new file mode 100644 index 000000000..f03ad1fe5 --- /dev/null +++ b/kpart/CMakeLists.txt @@ -0,0 +1,33 @@ +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/cmake/modules ${CMAKE_MODULE_PATH}) + +find_package(KDE4 REQUIRED) +include (KDE4Defaults) + +add_definitions (${QT_DEFINITIONS} ${KDE4_DEFINITIONS}) +include_directories (${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${KDE4_INCLUDES}) + +#Don't build test shell +#add_subdirectory(shell) + +set(plasma_kpartscripting_SRCS + scripting/layouttemplatepackagestructure.cpp + scripting/rect.cpp + scripting/scriptengine.cpp + scripting/widget.cpp +) + +set(plasma_kpart_SRCS + ${plasma_kpartscripting_SRCS} + plasmakpartcorona.cpp + plasmakpartview.cpp + plasmakpart.cpp +) + +kde4_add_plugin(plasma-kpart ${plasma_kpart_SRCS}) + +target_link_libraries(plasma-kpart ${QT_QTSCRIPT_LIBRARY} ${KDE4_PLASMA_LIBS} ${KDE4_KNEWSTUFF2_LIBS} ${KDE4_KIO_LIBS} ${X11_LIBRARIES} ${KDE4_KFILE_LIBS} ${KDE4_KPARTS_LIBS} ) + +install(TARGETS plasma-kpart DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-kpart.desktop DESTINATION ${SERVICES_INSTALL_DIR}) + +install(FILES plasmakpart.h plasmakpartview.h plasmakpartcorona.h DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel ) diff --git a/kpart/README b/kpart/README new file mode 100644 index 000000000..dc60a06e3 --- /dev/null +++ b/kpart/README @@ -0,0 +1,7 @@ +=== What === +This is a generic shell that can be embedded in any KDE application +which supports KParts to provide easy capabilities to add a plasma-based +dashboard to their application. + +=== How can I use this code? === +See http://techbase.kde.org/Development/Tutorials/Plasma/ApplicationShell diff --git a/kpart/kpart.kdev4 b/kpart/kpart.kdev4 new file mode 100644 index 000000000..636616f2e --- /dev/null +++ b/kpart/kpart.kdev4 @@ -0,0 +1,3 @@ +[Project] +Manager=KDevCMakeManager +Name=kpart diff --git a/kpart/plasma-kpart.desktop b/kpart/plasma-kpart.desktop new file mode 100644 index 000000000..07fd0b863 --- /dev/null +++ b/kpart/plasma-kpart.desktop @@ -0,0 +1,12 @@ +[Desktop Entry] +Name=plasma-kpart +Name[da]=plasma-kpart +Name[es]=plasma-kpart +Name[pt]=plasma-kpart +Name[pt_BR]=plasma-kpart +Name[sv]=Plasma-delprogram +Name[uk]=Модуль Плазми +Name[x-test]=xxplasma-kpartxx +Type=Service +ServiceTypes=KParts/Part +X-KDE-Library=plasma-kpart diff --git a/kpart/plasmakpart.cpp b/kpart/plasmakpart.cpp new file mode 100644 index 000000000..c8a88f54a --- /dev/null +++ b/kpart/plasmakpart.cpp @@ -0,0 +1,185 @@ +/* + * Copyright 2006-2008 Aaron Seigo + * Copyright 2009 Marco Martin + * Copyright 2010 Ryan Rix + * Copyright 2010 Siddharth Sharma + * + * 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 "plasmakpart.h" + +#include "plasmakpartcorona.h" +#include "plasmakpartview.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +K_PLUGIN_FACTORY(plasmaKPartFactory, registerPlugin();) +K_EXPORT_PLUGIN(plasmaKPartFactory("plasma-kpart","plasma-kpart") ) + +PlasmaKPart::PlasmaKPart(QWidget *parentWidget, QObject *parent, const QVariantList& args) + : KParts::ReadOnlyPart(parent), + m_corona(0), + m_view(0), + m_service(0) +{ + setComponentData( plasmaKPartFactory::componentData() ); + + KGlobal::locale()->insertCatalog("libplasma"); + KGlobal::locale()->insertCatalog("plasmagenericshell"); + KGlobal::locale()->insertCatalog("plasma-kpart"); + + setThemeDefaults(); + + m_view = new PlasmaKPartView(0, 1, parentWidget); + m_view->installEventFilter(this); + setWidget(m_view); + + // initialize the plugin loader + if( args.length() > 0 ) + { + Plasma::PluginLoader* loader = qVariantValue( args.first() ); + if( loader ) + { + Plasma::PluginLoader::setPluginLoader( loader ); + } + } + + if ( args.length() > 1 ) + m_category = args.at(1).value(); + + // this line initializes the corona. + corona(); +} + +PlasmaKPart::~PlasmaKPart() +{ +} + +void PlasmaKPart::setThemeDefaults() +{ + KConfigGroup cg(KSharedConfig::openConfig("plasmarc"), "Theme-plasma-netbook" ); + const QString themeName = cg.readEntry("name", "air" ); + Plasma::Theme::defaultTheme()->setUseGlobalSettings(false); + Plasma::Theme::defaultTheme()->setThemeName(themeName); + + cg = KConfigGroup(KGlobal::config(), "General"); + + Plasma::Theme::defaultTheme()->setFont(cg.readEntry("desktopFont", QFont("Sans") )); +} + +void PlasmaKPart::cleanup() +{ + if (m_corona) { + m_corona->saveLayout(); + } + + if (!m_view->containment()) { + return; + } + + // save the mapping of Views to Containments at the moment + // of application exit so we can restore that when we start again. + KConfigGroup viewIds(KGlobal::config(), "ViewIds"); + viewIds.deleteGroup(); + viewIds.writeEntry(QString::number(m_view->containment()->id()), 1); + + delete m_view; + m_view = 0; + + delete m_corona; + m_corona = 0; + + //TODO: This manual sync() should not be necessary? + syncConfig(); +} + +void PlasmaKPart::syncConfig() +{ + KGlobal::config()->sync(); +} + +PlasmaKPartCorona* PlasmaKPart::corona() +{ + if (!m_corona) { + m_corona = new PlasmaKPartCorona(this); + connect(m_corona, SIGNAL(containmentAdded(Plasma::Containment*)), this, SLOT(createView(Plasma::Containment*))); + connect(m_corona, SIGNAL(configSynced()), this, SLOT(syncConfig())); + + m_corona->setItemIndexMethod(QGraphicsScene::NoIndex); + m_corona->initializeLayout(); + + m_view->show(); + } + + return m_corona; +} + +void PlasmaKPart::createView(Plasma::Containment *containment) +{ + KConfigGroup viewIds(KGlobal::config(), "ViewIds"); + int id = viewIds.readEntry(QString::number(containment->id()), 1); + + kDebug() << "new containment" << (QObject*)containment << containment->id()<<"view id"<setContainment(containment); + emit viewCreated(); +} + +void PlasmaKPart::addApplet(const QString& name, const QVariantList& args, const QRectF& geometry ) +{ + containment()->addApplet(name, args, geometry); +} + +Plasma::Applet::List PlasmaKPart::listActiveApplets( ) +{ + return containment()->applets(); +} + +Plasma::Containment* PlasmaKPart::containment() +{ + return corona()->containments().first(); +} + +bool PlasmaKPart::setPluginLoader( Plasma::PluginLoader* loader ) +{ + if ( Plasma::PluginLoader::pluginLoader() ) { + return false; + } + + Plasma::PluginLoader::setPluginLoader( loader ); + + return true; +} + +QString PlasmaKPart::category() +{ + return m_category; +} + +#include "plasmakpart.moc" diff --git a/kpart/plasmakpart.h b/kpart/plasmakpart.h new file mode 100644 index 000000000..a00888868 --- /dev/null +++ b/kpart/plasmakpart.h @@ -0,0 +1,117 @@ +/* + * Copyright 2006-2008 Aaron Seigo + * Copyright 2009 Marco Martin + * Copyright 2010 Ryan Rix + * Copyright 2010 Siddharth Sharma + * + * 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 PLASMAKPART_H +#define PLASMAKPART_H + +class PlasmaKPartView; +class PlasmaKPartCorona; + +#include +Q_DECLARE_METATYPE( Plasma::Containment* ); +namespace Plasma +{ + class Applet; + class PluginLoader; +} + +#include +#include +class KDialog; + +#include +class QVariant; +class QVBoxLayout; + +class PlasmaKPart : public KParts::ReadOnlyPart +{ +Q_OBJECT +Q_PROPERTY( Plasma::Applet::List activeApplets READ listActiveApplets ); +public: + PlasmaKPart(QWidget* parentWidget, QObject* parent, const QVariantList&); + ~PlasmaKPart(); + + void notifyStartup(bool completed); + + PlasmaKPartCorona* corona(); + Plasma::Containment* containment(); + QString category(); + +public Q_SLOTS: + /** + * Add an applet to the currently running containment. + * + * @short Add an applet to the containment + * @author Ryan Rix + * @version 0.01 + **/ + void addApplet(const QString& pluginName, const QVariantList& args = QVariantList(), const QRectF& dimensions = QRectF()); + + /** + * Sets the application-specific plugin loader. This allows + * applications which need to add internal applets (such + * as existing QWidget-based dashboard plugins), services or + * data engines to the Plasma dashboard. The preferred way to + * set this loader is by passing it to the KPart wrapped in a + * QVariant in the @p args parameter of the KPart constructor. + * This method is provided for applications which cannot set + * the loader in this method. + * The method will return false if Plasma already has a + * PluginLoader in memory, and will return true if the PluginLoader + * is successfully set. + * + * @param loader The loader which you want Plasma to query for + * new Applets, Data Engines and Services. + * @return True if the loader was successfully set, false otherwise + * (If Plasma already has a PluginLoader in memory) + * + * @short Set application-specific plugin loader + **/ + bool setPluginLoader( Plasma::PluginLoader* loader ); + + /** + * Returns a list of active applets in the containment. + * + * @return A list of the containment's Applets + **/ + Plasma::Applet::List listActiveApplets( ); + +private Q_SLOTS: + void cleanup(); + void syncConfig(); + void createView(Plasma::Containment* containment); + void setThemeDefaults(); + +private: + PlasmaKPartCorona* m_corona; + PlasmaKPartView* m_view; + QString m_category; + KService::Ptr m_service; + QHash* m_appletList; + QVBoxLayout* m_configLayout; + +Q_SIGNALS: + void viewCreated(); +}; + +#endif // multiple inclusion guard + diff --git a/kpart/plasmakpartcorona.cpp b/kpart/plasmakpartcorona.cpp new file mode 100644 index 000000000..4e3460701 --- /dev/null +++ b/kpart/plasmakpartcorona.cpp @@ -0,0 +1,94 @@ +/* + * Copyright 2008 Aaron Seigo + * Copyright 2010 Ryan Rix + * Copyright 2010 Siddharth Sharma + * + * 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 "plasmakpartcorona.h" + +#include "plasmakpart.h" + +#include + +#include + +#include +#include +#include "scripting/scriptengine.h" + +PlasmaKPartCorona::PlasmaKPartCorona(QObject* parent) + : Plasma::Corona(parent) +{ + init(); +} + +void PlasmaKPartCorona::init() +{ + enableAction("Lock Widgets", false); + enableAction("Shortcut Settings", false); +} + +void PlasmaKPartCorona::loadDefaultLayout() +{ + // used to force a save into the config file + KConfigGroup invalidConfig; + Plasma::Containment* c = addContainment("newspaper"); + + if (!c) { + // do some error reporting? + return; + } + + evaluateScripts(PlasmaKPartScripting::ScriptEngine::defaultLayoutScripts()); + requestConfigSync(); +} + +void PlasmaKPartCorona::evaluateScripts(const QStringList &scripts) +{ + foreach (const QString &script, scripts) { + PlasmaKPartScripting::ScriptEngine scriptEngine(this); + connect(&scriptEngine, SIGNAL(printError(QString)), this, SLOT(printScriptError(QString))); + connect(&scriptEngine, SIGNAL(print(QString)), this, SLOT(printScriptMessage(QString))); + + QFile file(script); + if (file.open(QIODevice::ReadOnly | QIODevice::Text) ) { + QString code = file.readAll(); + kDebug() << "evaluating startup script:" << script; + scriptEngine.evaluateScript(code); + } + } +} + +void PlasmaKPartCorona::printScriptError(const QString &error) +{ + kWarning() << "Startup script errror:" << error; +} + +void PlasmaKPartCorona::printScriptMessage(const QString &error) +{ + kDebug() << "Startup script: " << error; +} + +Plasma::Containment* PlasmaKPartCorona::containment() +{ + QList list = containments(); + + return list.first(); // We only have one containment +} + +#include "plasmakpartcorona.moc" diff --git a/kpart/plasmakpartcorona.h b/kpart/plasmakpartcorona.h new file mode 100644 index 000000000..ade070cf2 --- /dev/null +++ b/kpart/plasmakpartcorona.h @@ -0,0 +1,57 @@ +/* + * Copyright 2008 Aaron Seigo + * Copyright 2010 Ryan Rix + * Copyright 2010 Siddharth Sharma + * + * 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 PLASMAKPARTCORONA_H +#define PLASMAKPARTCORONA_H + +#include + +namespace Plasma +{ + class Applet; +} // namespace Plasma + +/** + * @short A Corona with dashboard-y considerations + */ +class PlasmaKPartCorona : public Plasma::Corona +{ +Q_OBJECT +public: + PlasmaKPartCorona(QObject* parent); + + Plasma::Containment* containment(); + + void loadDefaultLayout(); + +private: + void evaluateScripts(const QStringList &scripts); + void init(); + +private Q_SLOTS: + void printScriptError(const QString &error); + void printScriptMessage(const QString &error); + +private: + Plasma::Applet* loadDefaultApplet(const QString &pluginName, Plasma::Containment *c); +}; + +#endif diff --git a/kpart/plasmakpartview.cpp b/kpart/plasmakpartview.cpp new file mode 100644 index 000000000..63f8aa39c --- /dev/null +++ b/kpart/plasmakpartview.cpp @@ -0,0 +1,85 @@ +/* + * Copyright 2007-2008 Aaron Seigo + * Copyright 2010 Ryan Rix + * Copyright 2010 Siddharth Sharma + * + * 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 "plasmakpartview.h" +#include "plasmakpartcorona.h" + +#include +#include + +PlasmaKPartView::PlasmaKPartView(Plasma::Containment* containment, int uid, QWidget* parent) + : Plasma::View(containment, uid, parent), + m_configurationMode(false) +{ + setFocusPolicy(Qt::NoFocus); + connectContainment(containment); + + setWallpaperEnabled( false ); +} + +PlasmaKPartView::~PlasmaKPartView() +{ +} + +void PlasmaKPartView::connectContainment(Plasma::Containment* containment) +{ + if (!containment) { + return; + } + + connect(this, SIGNAL(sceneRectAboutToChange()), this, SLOT(updateGeometry())); + connect(containment, SIGNAL(toolBoxVisibilityChanged(bool)), this, SLOT(updateConfigurationMode(bool))); +} + +void PlasmaKPartView::setContainment(Plasma::Containment* c) +{ + if (containment()) { + disconnect(containment(), 0, this, 0); + } + + Plasma::View::setContainment(c); + connectContainment(c); + updateGeometry(); +} + +void PlasmaKPartView::resizeEvent(QResizeEvent *event) +{ + Q_UNUSED(event) + updateGeometry(); + emit geometryChanged(); +} + +void PlasmaKPartView::updateGeometry() +{ + Plasma::Containment* c = containment(); + if (!c) { + return; + } + + kDebug() << "New containment geometry is" << c->geometry(); + + if (c->size().toSize() != size()) { + c->setMaximumSize(size()); + c->setMinimumSize(size()); + c->resize(size()); + } +} + +#include "plasmakpartview.moc" diff --git a/kpart/plasmakpartview.h b/kpart/plasmakpartview.h new file mode 100644 index 000000000..b677a1400 --- /dev/null +++ b/kpart/plasmakpartview.h @@ -0,0 +1,64 @@ +/* + * Copyright 2007-2008 Aaron Seigo + * Copyright 2010 Ryan Rix + * Copyright 2010 Siddharth Sharma + * + * 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 PLASMAKPARTVIEW_H +#define PLASMAKPARTVIEW_H + +#include +#include + +namespace Plasma +{ + class Containment; +} // namespace Plasma + +class PlasmaKPartView : public Plasma::View +{ +Q_OBJECT +public: + typedef Plasma::ImmutabilityType ImmutabilityType; + PlasmaKPartView(Plasma::Containment *containment, int uid, QWidget *parent = 0); + ~PlasmaKPartView(); + + /** + * hook up all needed signals to a containment + */ + void connectContainment(Plasma::Containment *containment); + + bool autoHide() const; + +public Q_SLOTS: + void setContainment(Plasma::Containment *containment); + void updateGeometry(); + +Q_SIGNALS: + void containmentActivated(); + void autoHideChanged(bool autoHide); + void geometryChanged(); + +protected: + void resizeEvent( QResizeEvent* event ); + +private: + bool m_configurationMode; +}; + +#endif // multiple inclusion guard diff --git a/kpart/scripting/backportglobal.h b/kpart/scripting/backportglobal.h new file mode 100644 index 000000000..45587a1cf --- /dev/null +++ b/kpart/scripting/backportglobal.h @@ -0,0 +1,364 @@ +/**************************************************************************** +** +** 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 +#include + +#define DECLARE_SELF(Class, __fn__) \ + Class* self = qscriptvalue_cast(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(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(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(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(ctx->argument(0)))); \ +} END_DECLARE_METHOD + + +#define DECLARE_POINTER_METATYPE(T) \ + Q_DECLARE_METATYPE(T*) \ + Q_DECLARE_METATYPE(QScript::Pointer::wrapped_pointer_type) + +namespace QScript +{ + +enum { + UserOwnership = 1 +}; + +template +class Pointer : public QSharedData +{ +public: + typedef T* pointer_type; + typedef QExplicitlySharedDataPointer > 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(var)) { + target = qvariant_cast(var); + } else if (qVariantCanConvert(var)) { + target = qvariant_cast(var)->operator T*(); + } else { + // look in prototype chain + target = 0; + int type = qMetaTypeId(); + int pointerType = qMetaTypeId(); + 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(var.data()))->operator T*(); + break; + } else { + target = static_cast(var.data()); + break; + } + } + proto = proto.prototype(); + } + } + } else if (value.isQObject()) { + QObject *qobj = value.toQObject(); + QByteArray typeName = QMetaType::typeName(qMetaTypeId()); + target = reinterpret_cast(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 +int registerPointerMetaType( + QScriptEngine *eng, + const QScriptValue &prototype = QScriptValue(), + T * /* dummy */ = 0 +) +{ + QScriptValue (*mf)(QScriptEngine *, T* const &) = Pointer::toScriptValue; + void (*df)(const QScriptValue &, T* &) = Pointer::fromScriptValue; + const int id = qMetaTypeId(); + qScriptRegisterMetaType_helper( + eng, id, reinterpret_cast(mf), + reinterpret_cast(df), + prototype); + eng->setDefaultPrototype(qMetaTypeId::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::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::wrapped_pointer_type *>(var.data()))->unsetFlags(UserOwnership); + } +} + +template +inline QScriptValue wrapPointer(QScriptEngine *eng, T *ptr, uint flags = 0) +{ + return eng->newVariant(qVariantFromValue(Pointer::create(ptr, flags))); +} + +} // namespace QScript + +#ifdef QGRAPHICSITEM_H + +namespace QScript { + +template +inline QScriptValue wrapGVPointer(QScriptEngine *eng, T *item) +{ + uint flags = item->parentItem() ? UserOwnership : 0; + return wrapPointer(eng, item, flags); +} + +} // namespace QScript + +#endif // QGRAPHICSITEM_H + +#endif // QTSCRIPTEXTENSIONS_GLOBAL_H diff --git a/kpart/scripting/layouttemplatepackagestructure.cpp b/kpart/scripting/layouttemplatepackagestructure.cpp new file mode 100644 index 000000000..e7bd75ae4 --- /dev/null +++ b/kpart/scripting/layouttemplatepackagestructure.cpp @@ -0,0 +1,42 @@ +/* + * Copyright 2010 Aaron Seigo + * + * 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 "layouttemplatepackagestructure.h" + +namespace PlasmaKPartScripting +{ + +LayoutTemplatePackageStructure::LayoutTemplatePackageStructure(QObject *parent) + : Plasma::PackageStructure(parent) +{ + setServicePrefix("plasma-layout-template"); + setDefaultPackageRoot("plasma/layout-templates"); + addFileDefinition("mainscript", "layout.js", "Main Script File"); + setRequired("mainscript", true); +} + +LayoutTemplatePackageStructure::~LayoutTemplatePackageStructure() +{ + +} + +} + +#include "layouttemplatepackagestructure.moc" + diff --git a/kpart/scripting/layouttemplatepackagestructure.h b/kpart/scripting/layouttemplatepackagestructure.h new file mode 100644 index 000000000..f3c7a0ebf --- /dev/null +++ b/kpart/scripting/layouttemplatepackagestructure.h @@ -0,0 +1,40 @@ +/* + * Copyright 2010 Aaron Seigo + * + * 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 TEMPLATETEMPLATEPACKAGE_H +#define TEMPLATETEMPLATEPACKAGE_H + +#include + +namespace PlasmaKPartScripting +{ + +class LayoutTemplatePackageStructure : public Plasma::PackageStructure +{ + Q_OBJECT + +public: + LayoutTemplatePackageStructure(QObject *parent = 0); + ~LayoutTemplatePackageStructure(); +}; + +} + +#endif + diff --git a/kpart/scripting/rect.cpp b/kpart/scripting/rect.cpp new file mode 100644 index 000000000..1c2a22260 --- /dev/null +++ b/kpart/scripting/rect.cpp @@ -0,0 +1,327 @@ +/* + * Copyright 2007 Richard J. Moore + * + * 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 +#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(), proto); + eng->setDefaultPrototype(qMetaTypeId(), proto); + + return eng->newFunction(ctor, proto); +} diff --git a/kpart/scripting/scriptengine.cpp b/kpart/scripting/scriptengine.cpp new file mode 100644 index 000000000..cb1a8508b --- /dev/null +++ b/kpart/scripting/scriptengine.cpp @@ -0,0 +1,374 @@ +/* + * Copyright 2009 Aaron Seigo + * + * 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 +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "widget.h" +#include "layouttemplatepackagestructure.h" + +QScriptValue constructQRectFClass(QScriptEngine *engine); + +namespace PlasmaKPartScripting +{ + +ScriptEngine::ScriptEngine(Plasma::Corona *corona, QObject *parent) + : QScriptEngine(parent), + m_corona(corona) +{ + Q_ASSERT(m_corona); + + m_containment = m_corona->containments().first(); + Q_ASSERT(m_containment); + + setupEngine(); + connect(this, SIGNAL(signalHandlerException(QScriptValue)), this, SLOT(exception(QScriptValue))); +} + +ScriptEngine::~ScriptEngine() +{ +} + +QScriptValue ScriptEngine::wrap(Plasma::Applet *w) +{ + Widget *wrapper = new Widget(w); + QScriptValue v = newQObject(wrapper, QScriptEngine::ScriptOwnership, + QScriptEngine::ExcludeSuperClassProperties | + QScriptEngine::ExcludeSuperClassMethods); + return v; +} + +ScriptEngine *ScriptEngine::envFor(QScriptEngine *engine) +{ + return static_cast(engine); +} + +QScriptValue ScriptEngine::print(QScriptContext *context, QScriptEngine *engine) +{ + if (context->argumentCount() < 1) { + return engine->undefinedValue(); + } + + const QString &msg = context->argument(0).toString(); + + if (!msg.isEmpty()) { + emit envFor(engine)->print(msg); + } + + return engine->undefinedValue(); +} + +QScriptValue ScriptEngine::knownWidgetTypes(QScriptContext *context, QScriptEngine *engine) +{ + Q_UNUSED(context) + Q_UNUSED(engine) + + QStringList widgets; + KPluginInfo::List infos = Plasma::Applet::listAppletInfo(); + + foreach (const KPluginInfo &info, infos) { + widgets.append(info.pluginName()); + } + + return qScriptValueFromValue(engine, widgets); +} + +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) { + kDebug() << "no arguments"; + return false; + } + + const QString layout = context->argument(0).toString(); + if (layout.isEmpty() || layout.contains("'")) { + kDebug() << "layout is empty"; + return false; + } + + const QString constraint = QString("[X-Plasma-Shell] == '%1' and [X-KDE-PluginInfo-Name] == '%2'") + .arg(KGlobal::mainComponent().componentName(),layout); + KService::List offers = KServiceTypeTrader::self()->query("Plasma/LayoutTemplate", constraint); + + if (offers.isEmpty()) { + kDebug() << "offers fail" << constraint; + return false; + } + + Plasma::PackageStructure::Ptr structure(new LayoutTemplatePackageStructure); + KPluginInfo info(offers.first()); + const QString path = KStandardDirs::locate("data", structure->defaultPackageRoot() + '/' + info.pluginName() + '/'); + if (path.isEmpty()) { + kDebug() << "script path is empty"; + return false; + } + + Plasma::Package package(path, structure); + const QString scriptFile = package.filePath("mainscript"); + if (scriptFile.isEmpty()) { + kDebug() << "scriptfile is empty"; + return false; + } + + QFile file(scriptFile); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + kWarning() << QString("Unable to load script file: %1").arg(path); + return false; + } + + QString script = file.readAll(); + if (script.isEmpty()) { + kDebug() << "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); + env->evaluateScript(script, path); + return true; +} + +void ScriptEngine::setupEngine() +{ + QScriptValue v = globalObject(); + v.setProperty("print", newFunction(ScriptEngine::print)); + v.setProperty("QRectF", constructQRectFClass(this)); + v.setProperty("knownWidgetTypes", newFunction(ScriptEngine::fileExists)); + v.setProperty("fileExists", newFunction(ScriptEngine::fileExists)); + v.setProperty("loadTemplate", newFunction(ScriptEngine::loadTemplate)); + v.setProperty("widgets", newFunction(ScriptEngine::widgets)); + v.setProperty("addWidget", newFunction(ScriptEngine::addWidget)); + v.setProperty("applicationVersion", KGlobal::mainComponent().aboutData()->version(), + QScriptValue::PropertyGetter | QScriptValue::ReadOnly | QScriptValue::Undeletable); + v.setProperty("scriptingVersion", newVariant(PLASMA_KPART_SCRIPTING_VERSION), + QScriptValue::PropertyGetter | QScriptValue::ReadOnly | QScriptValue::Undeletable); + v.setProperty("platformVersion", KDE::versionString(), + QScriptValue::PropertyGetter | QScriptValue::ReadOnly | QScriptValue::Undeletable); + + setGlobalObject(v); +} + +bool ScriptEngine::evaluateScript(const QString &script, const QString &path) +{ + //kDebug() << "evaluating" << m_editor->toPlainText(); + evaluate(script, path); + if (hasUncaughtException()) { + //kDebug() << "catch the exception!"; + QString error = QString("Error: %1 at line %2\n\nBacktrace:\n%3").arg( + uncaughtException().toString(), + QString::number(uncaughtExceptionLineNumber()), + uncaughtExceptionBacktrace().join("\n ")); + emit printError(error); + return false; + } + + return true; +} + +void ScriptEngine::exception(const QScriptValue &value) +{ + //kDebug() << "exception caught!" << value.toVariant(); + emit printError(value.toVariant().toString()); +} + +QStringList ScriptEngine::pendingUpdateScripts() +{ + const QString appName = KGlobal::activeComponent().aboutData()->appName(); + QStringList scripts = KGlobal::dirs()->findAllResources("data", appName + "/plasma/layout/updates/*.js"); + QStringList scriptPaths; + + if (scripts.isEmpty()) { + //kDebug() << "no update scripts"; + return scriptPaths; + } + + KConfigGroup cg(KGlobal::config(), "Updates"); + QStringList performed = cg.readEntry("performed", QStringList()); + const QString localDir = KGlobal::dirs()->localkdedir(); + const QString localXdgDir = KGlobal::dirs()->localxdgdatadir(); + + foreach (const QString &script, scripts) { + if (performed.contains(script)) { + continue; + } + + if (script.startsWith(localDir) || script.startsWith(localXdgDir)) { + kDebug() << "skipping user local script: " << script; + continue; + } + + scriptPaths.append(script); + performed.append(script); + } + + cg.writeEntry("performed", performed); + KGlobal::config()->sync(); + return scriptPaths; +} + +QStringList ScriptEngine::defaultLayoutScripts() +{ + const QString appName = KGlobal::activeComponent().aboutData()->appName(); + QStringList scripts = KGlobal::dirs()->findAllResources("data", appName + "/plasma/layout/init/*.js"); + QStringList scriptPaths; + + if (scripts.isEmpty()) { + //kDebug() << "no javascript based layouts"; + return scriptPaths; + } + + const QString localDir = KGlobal::dirs()->localkdedir(); + const QString localXdgDir = KGlobal::dirs()->localxdgdatadir(); + + QSet scriptNames; + foreach (const QString &script, scripts) { + if (script.startsWith(localDir) || script.startsWith(localXdgDir)) { + kDebug() << "skipping user local script: " << script; + continue; + } + + QFileInfo f(script); + QString filename = f.fileName(); + if (!scriptNames.contains(filename)) { + scriptNames.insert(filename); + scriptPaths.append(script); + } + } + + return scriptPaths; +} + +QScriptValue ScriptEngine::widgets(QScriptContext *context, QScriptEngine *engine) +{ + ScriptEngine *env = ScriptEngine::envFor(engine); + + const QString widgetType = context->argumentCount() > 0 ? context->argument(0).toString() : QString(); + QScriptValue widgets = engine->newArray(); + int count = 0; + + foreach (Plasma::Applet *widget, env->m_containment->applets()) { + if (widgetType.isEmpty() || widget->pluginName() == widgetType) { + widgets.setProperty(count, env->wrap(widget)); + ++count; + } + } + + widgets.setProperty("length", count); + return widgets; +} + +QScriptValue ScriptEngine::addWidget(QScriptContext *context, QScriptEngine *engine) +{ + if (context->argumentCount() == 0) { + return context->throwError("widgetById requires a name of a widget or a widget object"); + } + quint16 row = 0; + quint16 column = 0; + + ScriptEngine *env = ScriptEngine::envFor(engine); + + if (context->argumentCount() == 3) { + QScriptValue v = context->argument(1); + if (v.isNumber()) { + row = v.toUInt16(); + } + v = context->argument(2); + if (v.isNumber()) { + column = v.toUInt16(); + } + kDebug() << "Calculated position as" << row << column; + } + + QScriptValue v = context->argument(0); + Plasma::Applet *applet = 0; + if (v.isString()) { + // FIXME: Using QMetaObject::invokeMethod until the newspaper's API is exported... Fuuuu + // applet = env->m_containment->addApplet(v.toString(), row, column); + QMetaObject::invokeMethod(env->m_containment, "addApplet", + Qt::DirectConnection, + Q_RETURN_ARG(Plasma::Applet*, applet), + Q_ARG(QString, v.toString()), + Q_ARG(int, row), Q_ARG(int, column)); + if (applet) { + ScriptEngine *env = ScriptEngine::envFor(engine); + return env->wrap(applet); + } + } else if (Widget *widget = qobject_cast(v.toQObject())) { + applet = widget->applet(); + + // FIXME: Using QMetaObject::invokeMethod until the newspaper's API is exported... Fuuuu + // env->m_containment->addApplet(applet, row, column); + QMetaObject::invokeMethod(env->m_containment, "addApplet", + Qt::DirectConnection, + Q_RETURN_ARG(Plasma::Applet*, applet), + Q_ARG(QString, v.toString()), + Q_ARG(int, row), Q_ARG(int, column)); + return v; + } + + return engine->undefinedValue(); +} + +QScriptValue ScriptEngine::theme(QScriptContext *context, QScriptEngine *engine) +{ + Q_UNUSED(engine) + + if (context->argumentCount() > 0) { + const QString newTheme = context->argument(0).toString(); + Plasma::Theme::defaultTheme()->setThemeName(newTheme); + } + + return Plasma::Theme::defaultTheme()->themeName(); +} + +} + +#include "scriptengine.moc" + diff --git a/kpart/scripting/scriptengine.h b/kpart/scripting/scriptengine.h new file mode 100644 index 000000000..046a73943 --- /dev/null +++ b/kpart/scripting/scriptengine.h @@ -0,0 +1,81 @@ +/* + * Copyright 2009 Aaron Seigo + * + * 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 +#include + +namespace Plasma +{ + class Applet; + class Containment; + class Corona; +} // namespace Plasma + +namespace PlasmaKPartScripting +{ + +class ScriptEngine : public QScriptEngine +{ + Q_OBJECT + +public: + explicit ScriptEngine(Plasma::Corona *corona, QObject *parent = 0); + ~ScriptEngine(); + + static QStringList pendingUpdateScripts(); + static QStringList defaultLayoutScripts(); + + bool evaluateScript(const QString &script, const QString &path = QString()); + QScriptValue wrap(Plasma::Applet *w); + + static ScriptEngine *envFor(QScriptEngine *engine); + +Q_SIGNALS: + void print(const QString &string); + void printError(const QString &string); + +private: + void setupEngine(); + + static QScriptValue print(QScriptContext *context, QScriptEngine *engine); + static QScriptValue fileExists(QScriptContext *context, QScriptEngine *engine); + static QScriptValue loadTemplate(QScriptContext *context, QScriptEngine *engine); + static QScriptValue theme(QScriptContext *context, QScriptEngine *engine); + static QScriptValue widgets(QScriptContext *context, QScriptEngine *engine); + static QScriptValue addWidget(QScriptContext *context, QScriptEngine *engine); + static QScriptValue knownWidgetTypes(QScriptContext *context, QScriptEngine *engine); + +private Q_SLOTS: + void exception(const QScriptValue &value); + +private: + Plasma::Corona *m_corona; + Plasma::Containment *m_containment; + QScriptValue m_scriptSelf; + + static const int PLASMA_KPART_SCRIPTING_VERSION = 3; +}; + +} + +#endif + diff --git a/kpart/scripting/widget.cpp b/kpart/scripting/widget.cpp new file mode 100644 index 000000000..e701b332b --- /dev/null +++ b/kpart/scripting/widget.cpp @@ -0,0 +1,275 @@ +/* + * Copyright 2009 Aaron Seigo + * + * 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 + +#include +#include + +#include +#include +#include + +namespace PlasmaKPartScripting +{ + +class Widget::Private +{ +public: + Private() + : configDirty(false) + { + } + + QWeakPointer applet; + + KConfigGroup configGroup; + QStringList configGroupPath; + KConfigGroup globalConfigGroup; + QStringList globalConfigGroupPath; + bool configDirty : 1; +}; + +Widget::Widget(Plasma::Applet *applet, QObject *parent) + : QObject(parent), + d(new Widget::Private) +{ + d->applet = applet; +} + +Widget::~Widget() +{ + if (d->configDirty) { + reloadConfig(); + } + + delete d; +} + +void Widget::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); + } +} + +QStringList Widget::currentConfigGroup() const +{ + return d->configGroupPath; +} + +QStringList Widget::configKeys() const +{ + if (d->configGroup.isValid()) { + return d->configGroup.keyList(); + } + + return QStringList(); +} + +QStringList Widget::configGroups() const +{ + if (d->configGroup.isValid()) { + return d->configGroup.groupList(); + } + + return QStringList(); +} + +QVariant Widget::readConfig(const QString &key, const QVariant &def) const +{ + if (d->configGroup.isValid()) { + return d->configGroup.readEntry(key, def); + } else { + return QVariant(); + } +} + +void Widget::writeConfig(const QString &key, const QVariant &value) +{ + if (d->configGroup.isValid()) { + d->configGroup.writeEntry(key, value); + d->configDirty = true; + } +} + +void Widget::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 Widget::currentGlobalConfigGroup() const +{ + return d->globalConfigGroupPath; +} + +QStringList Widget::globalConfigKeys() const +{ + if (d->globalConfigGroup.isValid()) { + return d->globalConfigGroup.keyList(); + } + + return QStringList(); +} + +QStringList Widget::globalConfigGroups() const +{ + if (d->globalConfigGroup.isValid()) { + return d->globalConfigGroup.groupList(); + } + + return QStringList(); +} + +QVariant Widget::readGlobalConfig(const QString &key, const QVariant &def) const +{ + if (d->globalConfigGroup.isValid()) { + return d->globalConfigGroup.readEntry(key, def); + } else { + return QVariant(); + } +} + +void Widget::writeGlobalConfig(const QString &key, const QVariant &value) +{ + if (d->globalConfigGroup.isValid()) { + d->globalConfigGroup.writeEntry(key, value); + d->configDirty = true; + } +} + +void Widget::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 Widget::version() const +{ + Plasma::Applet *app = applet(); + if (!app) { + return QString(); + } + + QString type = app->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(); +} + +Plasma::Applet *Widget::applet() const +{ + return d->applet.data(); +} + +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()->pluginName(); + } + + return QString(); +} + +void Widget::remove() +{ + if (d->applet) { + d->applet.data()->destroy(); + d->applet.clear(); + } +} + +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); + } +} + +void Widget::showConfigurationInterface() +{ + if (d->applet) { + d->applet.data()->showConfigurationInterface(); + } +} + +} + +#include "widget.moc" + diff --git a/kpart/scripting/widget.h b/kpart/scripting/widget.h new file mode 100644 index 000000000..d7d5409b4 --- /dev/null +++ b/kpart/scripting/widget.h @@ -0,0 +1,98 @@ +/* + * Copyright 2010 Aaron Seigo + * + * 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 +#include +#include + +namespace Plasma +{ + class Applet; +} // namespace Plasma + +namespace PlasmaKPartScripting +{ + +class Widget : public QObject +{ + 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) + +public: + explicit Widget(Plasma::Applet *applet, QObject *parent = 0); + ~Widget(); + + 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; + + QRectF geometry() const; + void setGeometry(const QRectF &geometry); + + QString version() const; + + uint id() const; + QString type() const; + + /** +FIXME: what should the index(es?) be given that we're in the newspaper containment + int index() const; + void setIndex(int index); + */ + + virtual Plasma::Applet *applet() const; + +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(); + void remove(); + void showConfigurationInterface(); + +private: + class Private; + Private * const d; +}; + +} + +#endif + diff --git a/kpart/shell/CMakeLists.txt b/kpart/shell/CMakeLists.txt new file mode 100644 index 000000000..3d417a134 --- /dev/null +++ b/kpart/shell/CMakeLists.txt @@ -0,0 +1,17 @@ +set(plasma_kpart_shell_SRCS + main.cpp + containmentshell.cpp + testshellpluginloader.cpp + appletselector.cpp +) + +kde4_add_ui_files(plasma_kpart_shell_SRCS appletselector.ui) +kde4_add_executable(plasma-kpart-shell ${plasma_kpart_shell_SRCS}) + +target_link_libraries(plasma-kpart-shell ${KDE4_KDEUI_LIBS} ${KDE4_KPARTS_LIBS} ${KDE4_PLASMA_LIBS} ) + +########### install files ############### +install(TARGETS plasma-kpart-shell ${INSTALL_TARGETS_DEFAULT_ARGS} ) +install( FILES plasma-kpart-shell.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} ) +install(FILES plasma-default-layoutrc DESTINATION ${DATA_INSTALL_DIR}/plasma-kpart-shell/) +install( FILES plasma-kpart-shellui.rc DESTINATION ${DATA_INSTALL_DIR}/plasma-kpart-shell/ ) diff --git a/kpart/shell/appletselector.cpp b/kpart/shell/appletselector.cpp new file mode 100644 index 000000000..87263a975 --- /dev/null +++ b/kpart/shell/appletselector.cpp @@ -0,0 +1,67 @@ +/* + * Copyright 2010 Aleix Pol Gonzalez + * + * This library 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 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "appletselector.h" +#include "ui_appletselector.h" + +#include +#include + +AppletSelector::AppletSelector(QObject* parent, const QVariantList& args) + : KDialog() +{ + Q_UNUSED(args); + + setButtons(Close); + QWidget* w = new QWidget(this); + + m_ui = new Ui::AppletSelector; + m_ui->setupUi(w); + + m_ui->plugins->header()->setSortIndicator(0, Qt::AscendingOrder); + + setMainWidget(w); + + QStandardItemModel* model = new QStandardItemModel(this); + const KPluginInfo::List list= Plasma::Applet::listAppletInfo(); + foreach(const KPluginInfo& info, list) { + QStandardItem* item = new QStandardItem(KIcon(info.icon()), info.name()); + item->setEditable(false); + item->setToolTip(info.comment()); + item->setData(info.pluginName(), Qt::UserRole+1); + + model->appendRow(item); + } + + m_ui->plugins->setModel(model); + + connect(m_ui->plugins, SIGNAL(doubleClicked(QModelIndex)), SLOT(selected(QModelIndex))); +} + +AppletSelector::~AppletSelector() +{ + delete m_ui; +} + +void AppletSelector::selected(const QModelIndex& idx) +{ + emit addApplet(idx.data(Qt::UserRole+1).toString()); +} + +#include "appletselector.moc" diff --git a/kpart/shell/appletselector.h b/kpart/shell/appletselector.h new file mode 100644 index 000000000..b646b359e --- /dev/null +++ b/kpart/shell/appletselector.h @@ -0,0 +1,44 @@ +/* This file is part of KDevelop + Copyright 2010 Aleix Pol Gonzalez + + This library 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 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef APPLETSELECTOR_H +#define APPLETSELECTOR_H + +#include + +class QModelIndex; +namespace Ui { class AppletSelector; } + +class AppletSelector : public KDialog +{ +Q_OBJECT +public: + explicit AppletSelector(QObject* parent = 0, const QVariantList& args = QVariantList()); + ~AppletSelector(); +public slots: + void selected(const QModelIndex& idx); + +signals: + void addApplet(const QString& name); + +private: + Ui::AppletSelector* m_ui; +}; + +#endif // APPLETSELECTOR_H diff --git a/kpart/shell/appletselector.ui b/kpart/shell/appletselector.ui new file mode 100644 index 000000000..19742409a --- /dev/null +++ b/kpart/shell/appletselector.ui @@ -0,0 +1,44 @@ + + + AppletSelector + + + + 0 + 0 + 400 + 300 + + + + + + + Double-click on the widget you want to add: + + + + + + + false + + + false + + + true + + + false + + + false + + + + + + + + diff --git a/kpart/shell/containmentshell.cpp b/kpart/shell/containmentshell.cpp new file mode 100644 index 000000000..88036f0fe --- /dev/null +++ b/kpart/shell/containmentshell.cpp @@ -0,0 +1,109 @@ +/* +* Copyright 2010 Ryan Rix +* Copyright 2010 Siddharth Sharma +* +* 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 "containmentshell.h" +#include "testshellpluginloader.h" +#include "appletselector.h" + +#include +#include +#include +#include +#include + + +#include + +#include + +ContainmentShell::ContainmentShell() + : KParts::MainWindow( ), + m_dialog(0) +{ + setXMLFile("plasma-kpart-shellui.rc"); + + + KAction* action = KStandardAction::quit(qApp, SLOT(quit()), actionCollection()); + + action = new KAction("&Configure", actionCollection()); + connect(action, SIGNAL(triggered()), this, SLOT(optionsPreferences())); + actionCollection()->addAction("options_configure", action); + + // this routine will find and load our Part. it finds the Part by + // name which is a bad idea usually.. but it's alright in this + // case since our Part is made for this Shell + KService::Ptr service = KService::serviceByDesktopPath( "plasma-kpart.desktop" ); + + if (service) + { + Plasma::PluginLoader* loader = new TestShellPluginLoader(); + + QVariantList args = QVariantList() << qVariantFromValue(loader) << "Online Services"; + + // now that the Part is loaded, we cast it to a Part to get + // our hands on it + m_part = service->createInstance(0, args); + if (m_part) + { + // tell the KParts::MainWindow that this is indeed the main widget + setCentralWidget(m_part->widget()); + + // and integrate the part's GUI with the shell's + createGUI(m_part); + + } + else + { + // For whatever reason the part didn't load + KMessageBox::error(this, "Could not instantiate our Part!"); + qApp->quit(); + } + } + else + { + // if we couldn't find our Part, we exit since the Shell by + // itself can't do anything useful + KMessageBox::error(this, "Could not find our Part!"); + qApp->quit(); + // we return here, cause qApp->quit() only means "exit the + // next time we enter the event loop... + return; + } + + // apply the saved mainwindow settings, if any, and ask the mainwindow + // to automatically save settings if changed: window size, toolbar + // position, icon size, etc. + setAutoSaveSettings(); +} + +ContainmentShell::~ContainmentShell() +{ +} + +void ContainmentShell::optionsPreferences() +{ + if( !m_dialog ) + { + m_dialog = new AppletSelector( m_part ); + connect( m_dialog, SIGNAL(addApplet(QString)), m_part, SLOT(addApplet(QString)) ); + } + m_dialog->show(); +} + +#include "containmentshell.moc" diff --git a/kpart/shell/containmentshell.h b/kpart/shell/containmentshell.h new file mode 100644 index 000000000..3811424ed --- /dev/null +++ b/kpart/shell/containmentshell.h @@ -0,0 +1,51 @@ +/* +* Copyright 2010 Ryan Rix +* Copyright 2010 Siddharth Sharma +* +* 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. +*/ + +#ifndef CONTAINMENTSHELL_H +#define CONTAINMENTSHELL_H + +#include "../plasmakpart.h" + +#include +#include + +/** + * This is the application "Shell". It has a menubar, toolbar, and + * statusbar but relies on the "Part" to do all the real work. + * + * @short Generic Application Shell + * @author Ryan Rix + * @version 0.01 + */ +class ContainmentShell : public KParts::MainWindow +{ +Q_OBJECT +public: + ContainmentShell(); + virtual ~ContainmentShell(); + +public Q_SLOTS: + void optionsPreferences(); + +private: + KParts::Part* m_part; + KDialog* m_dialog; +}; + +#endif // CONTAINMENTSHELL_H diff --git a/kpart/shell/main.cpp b/kpart/shell/main.cpp new file mode 100644 index 000000000..343ab119b --- /dev/null +++ b/kpart/shell/main.cpp @@ -0,0 +1,44 @@ +/* +* Copyright 2010 Ryan Rix +* +* 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 "containmentshell.h" +#include +#include +#include + +static const char version[] = "0.1"; + +int main(int argc, char** argv) +{ + KAboutData about("plasma-kpart-shell", 0, ki18n("Plasma KPart Shell"), version, ki18n("A KDE KPart Application"), KAboutData::License_GPL, ki18n("(C) 2010 Ryan Rix"), KLocalizedString(), 0, "ry@n.rix.si"); + about.addAuthor( ki18n("Ryan Rix"), KLocalizedString(), "ry@n.rix.si" ); + KCmdLineArgs::init(argc, argv, &about); + + KApplication app; + + // see if we are starting with session management + if (app.isSessionRestored()) + RESTORE(ContainmentShell) + else + { + ContainmentShell* widget = new ContainmentShell; + widget->show(); + } + + return app.exec(); +} diff --git a/kpart/shell/plasma-default-layoutrc b/kpart/shell/plasma-default-layoutrc new file mode 100644 index 000000000..500c8c789 --- /dev/null +++ b/kpart/shell/plasma-default-layoutrc @@ -0,0 +1,61 @@ +[Containments][1] +activity=Newspaper +desktop=-1 +formfactor=0 +geometry=806,0,800,480 +immutability=1 +location=0 +plugin=newspaper +screen=0 +wallpaperplugin=image +wallpaperpluginmode=SingleImage +zvalue=0 + +[Containments][1][ToolBox] +corner=7 +offset=0 + +[Containments][1][Applets][1] +geometry=14,38,343,236 +immutability=1 +plugin=news +zvalue=52 + +[Containments][1][Applets][1][LayoutInformation] +Column=0 +Order=0 + + +[Containments][1][Applets][2] +geometry=14,278,343,188 +immutability=1 +plugin=weather +zvalue=57 + +[Containments][1][Applets][2][LayoutInformation] +Column=0 +Order=1 + +[Containments][1][Applets][3] +geometry=1000,38,424,241 +immutability=1 +plugin=opendesktop +zvalue=47 + +[Containments][1][Applets][3][LayoutInformation] +Column=1 +Order=0 + +[Containments][1][Applets][4] +geometry=1000,283,424,182 +immutability=1 +plugin=knowledgebase +zvalue=47 + +[Containments][1][Applets][4][LayoutInformation] +Column=1 +Order=1 + + +[General] +immutability=1 diff --git a/kpart/shell/plasma-kpart-shell.desktop b/kpart/shell/plasma-kpart-shell.desktop new file mode 100644 index 000000000..b93f6d0d3 --- /dev/null +++ b/kpart/shell/plasma-kpart-shell.desktop @@ -0,0 +1,22 @@ +[Desktop Entry] +Name=plasma-kpart-shell +Name[da]=plasma-kpart-shell +Name[es]=plasma-kpart-shell +Name[pt]=plasma-kpart-shell +Name[pt_BR]=plasma-kpart-shell +Name[sv]=Plasma-delprogramskal +Name[uk]=plasma-kpart-shell +Name[x-test]=xxplasma-kpart-shellxx +Exec=plasma-kpart-shell %i -caption "%c" +Icon=plasma-kpart-shell +Type=Application +X-DocPath=plasma-kpart-shell/index.html +GenericName=A KPart shell for Plasma +GenericName[da]=En KPart-skal til Plasma +GenericName[es]=Shell de KPart para Plasma +GenericName[pt]=Uma consola de KPart para o Plasma +GenericName[pt_BR]=Uma shell de KPart para o Plasma +GenericName[sv]=Ett delprogramskal för Plasma +GenericName[uk]=Оболонка модулів для Плазми +GenericName[x-test]=xxA KPart shell for Plasmaxx +Terminal=false diff --git a/kpart/shell/plasma-kpart-shellui.rc b/kpart/shell/plasma-kpart-shellui.rc new file mode 100644 index 000000000..8255d4434 --- /dev/null +++ b/kpart/shell/plasma-kpart-shellui.rc @@ -0,0 +1,31 @@ + + + + &File + + + + + + + + &Settings + + + + + + + + + + + + +Main Toolbar + + + + + + diff --git a/kpart/shell/testshellpluginloader.cpp b/kpart/shell/testshellpluginloader.cpp new file mode 100644 index 000000000..084f6a32d --- /dev/null +++ b/kpart/shell/testshellpluginloader.cpp @@ -0,0 +1,49 @@ +/* +* Copyright 2010 Ryan Rix +* +* 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 "testshellpluginloader.h" + +#include + +#include +#include +#include +#include + +TestShellPluginLoader::~TestShellPluginLoader() +{ +} + +Plasma::Applet* TestShellPluginLoader::internalLoadApplet (const QString &name, uint appletId, const QVariantList &args) +{ + kDebug() << "loadApplet called with" << name << appletId << args; + return 0; +} + +Plasma::DataEngine* TestShellPluginLoader::internalLoadDataEngine(const QString &name) +{ + kDebug() << "loadEngine called with" << name; + return 0; +} + +Plasma::Service* TestShellPluginLoader::internalLoadService(const QString &name, const QVariantList &args, QObject *parent) +{ + kDebug() << "loadService called with" << name << args << parent; + return 0; +} + diff --git a/kpart/shell/testshellpluginloader.h b/kpart/shell/testshellpluginloader.h new file mode 100644 index 000000000..01fd4ae80 --- /dev/null +++ b/kpart/shell/testshellpluginloader.h @@ -0,0 +1,35 @@ +/* +* Copyright 2010 Ryan Rix +* +* 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. +*/ + +#ifndef TESTSHELLPLUGINLOADER_H +#define TESTSHELLPLUGINLOADER_H + +#include + +class TestShellPluginLoader : public Plasma::PluginLoader +{ +public: + ~TestShellPluginLoader(); + + Plasma::Applet* internalLoadApplet (const QString &name, uint appletId = 0, + const QVariantList &args = QVariantList()); + Plasma::DataEngine* internalLoadDataEngine(const QString &name); + Plasma::Service* internalLoadService(const QString &name, const QVariantList &args, QObject *parent = 0); +}; + +#endif