Merge branch 'mart/interactiveconsole'

REVIEW:116085
This commit is contained in:
Marco Martin 2014-02-26 18:35:49 +01:00
commit 1fd741b5d3
10 changed files with 738 additions and 82 deletions

View File

@ -17,6 +17,7 @@ find_package(KF5CoreAddons REQUIRED)
find_package(KF5Crash REQUIRED)
find_package(KF5Solid REQUIRED)
find_package(KF5Activities REQUIRED)
find_package(KF5TextEditor REQUIRED)
set(scripting_SRC
@ -26,7 +27,6 @@ set(scripting_SRC
scripting/configgroup.cpp
scripting/desktopscriptengine.cpp
scripting/i18n.cpp
scripting/layouttemplatepackagestructure.cpp
scripting/panel.cpp
scripting/rect.cpp
scripting/scriptengine.cpp
@ -42,6 +42,7 @@ add_executable(plasma-shell
containmentconfigview.cpp
currentcontainmentactionsmodel.cpp
desktopview.cpp
interactiveconsole.cpp
kidenticongenerator.cpp
panelview.cpp
panelconfigview.cpp
@ -73,6 +74,7 @@ target_link_libraries(plasma-shell
KF5::Activities
KF5::GlobalAccel
KF5::DBusAddons
KF5::TextEditor
)
target_include_directories(plasma-shell PRIVATE "${CMAKE_BINARY_DIR}")

View File

@ -0,0 +1,577 @@
/*
* 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/Corona>
#include <Plasma/Package>
#include "scripting/desktopscriptengine.h"
#include "packages.h"
#include "shellpluginloader.h"
//TODO:
// interative help?
static const QString s_autosaveFileName("interactiveconsoleautosave.js");
static const QString s_kwinService = "org.kde.kwin.Scripting";
InteractiveConsole::InteractiveConsole(Plasma::Corona *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

@ -0,0 +1,116 @@
/*
* 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;
namespace KTextEditor
{
class Document;
} // namespace KParts
namespace Plasma
{
class Corona;
} // namespace Plasma
class ScriptEngine;
class InteractiveConsole : public QDialog
{
Q_OBJECT
public:
InteractiveConsole(Plasma::Corona *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);
Plasma::Corona *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

@ -124,3 +124,11 @@ void QmlWallpaperPackage::initPackage(Plasma::Package *package)
package->addDirectoryDefinition("translations", "locale", i18n("Translations"));
}
void LayoutTemplatePackage::initPackage(Plasma::Package *package)
{
package->setServicePrefix("plasma-layout-template");
package->setDefaultPackageRoot("plasma/layout-templates");
package->addFileDefinition("mainscript", "layout.js", i18n("Main Script File"));
package->setRequired("mainscript", true);
}

View File

@ -39,4 +39,11 @@ public:
void initPackage(Plasma::Package *package);
};
class LayoutTemplatePackage : public Plasma::PackageStructure
{
public:
void initPackage(Plasma::Package *package);
};
#endif // LOOKANDFEELPACKAGE_H

View File

@ -1,38 +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 "layouttemplatepackagestructure.h"
#include <klocalizedstring.h>
namespace WorkspaceScripting
{
void LayoutTemplatePackageStructure::initPackage(Plasma::Package *package)
{
package->setServicePrefix("plasma-layout-template");
package->setDefaultPackageRoot("plasma/layout-templates");
package->addFileDefinition("mainscript", "layout.js", i18n("Main Script File"));
package->setRequired("mainscript", true);
}
}
#include "layouttemplatepackagestructure.moc"

View File

@ -1,39 +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 TEMPLATETEMPLATEPACKAGE_H
#define TEMPLATETEMPLATEPACKAGE_H
#include <Plasma/PackageStructure>
namespace WorkspaceScripting
{
class LayoutTemplatePackageStructure : public Plasma::PackageStructure
{
Q_OBJECT
public:
void initPackage(Plasma::Package *package);
};
}
#endif

View File

@ -48,7 +48,7 @@
#include "containment.h"
#include "configgroup.h"
#include "i18n.h"
#include "layouttemplatepackagestructure.h"
#include "packages.h"
#include "widget.h"
QScriptValue constructQRectFClass(QScriptEngine *engine);
@ -269,7 +269,7 @@ QScriptValue ScriptEngine::loadTemplate(QScriptContext *context, QScriptEngine *
return false;
}
LayoutTemplatePackageStructure structure;
LayoutTemplatePackage structure;
Plasma::Package package(&structure);
KPluginInfo info(offers.first());
const QString path = QStandardPaths::locate(QStandardPaths::GenericDataLocation, package.defaultPackageRoot() + '/' + info.pluginName() + '/');

View File

@ -38,6 +38,8 @@
#include <ksycoca.h>
#include <kservicetypetrader.h>
#include <KGlobalAccel>
#include <KAuthorized>
#include <KWindowSystem>
#include "activity.h"
@ -48,6 +50,7 @@
#include "configview.h"
#include "shellpluginloader.h"
#include "osd.h"
#include "interactiveconsole.h"
#include "plasmashelladaptor.h"
@ -85,6 +88,7 @@ public:
QAction *addPanelAction;
QMenu *addPanelsMenu;
Plasma::Package lookNFeelPackage;
QWeakPointer<InteractiveConsole> console;
QTimer waitingPanelsTimer;
QTimer appConfigSyncTimer;
@ -474,12 +478,28 @@ void ShellCorona::toggleDashboard()
void ShellCorona::showInteractiveConsole()
{
if (KSharedConfig::openConfig()->isImmutable() || !KAuthorized::authorize("plasma-desktop/scripting_console")) {
return;
}
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());
}
void ShellCorona::loadScriptInInteractiveConsole(const QString &script)
{
showInteractiveConsole();
if (d->console) {
d->console.data()->loadScript(script);
}
}
void ShellCorona::checkActivities()

View File

@ -43,6 +43,9 @@ Plasma::Package ShellPluginLoader::internalLoadPackage(const QString &packageFor
} else if (packageFormat == "Plasma/Wallpaper") {
Plasma::PackageStructure *structure = new QmlWallpaperPackage();
return Plasma::Package(structure);
} else if (packageFormat == "Plasma/LayoutTemplate") {
Plasma::PackageStructure *structure = new LayoutTemplatePackage();
return Plasma::Package(structure);
} else {
return Plasma::Package();
}