Add an interactive Python console to the script manager
This commit is contained in:
parent
7c05b42dcd
commit
930a2aa2bf
|
@ -507,6 +507,7 @@ set(UI
|
|||
|
||||
scripting/installscriptdialog.ui
|
||||
scripting/scriptdialog.ui
|
||||
scripting/python/pythonconsole.ui
|
||||
|
||||
smartplaylists/querysearchpage.ui
|
||||
smartplaylists/querysortpage.ui
|
||||
|
@ -818,11 +819,13 @@ endif(APPLE)
|
|||
|
||||
if(HAVE_SCRIPTING_PYTHON)
|
||||
list(APPEND SOURCES
|
||||
scripting/python/pythonconsole.cpp
|
||||
scripting/python/pythonengine.cpp
|
||||
scripting/python/pythonscript.cpp
|
||||
)
|
||||
|
||||
list(APPEND HEADERS
|
||||
scripting/python/pythonconsole.h
|
||||
scripting/python/pythonengine.h
|
||||
)
|
||||
endif(HAVE_SCRIPTING_PYTHON)
|
||||
|
@ -898,6 +901,13 @@ list(APPEND OTHER_SOURCES
|
|||
remote/remoteconfig.cpp
|
||||
remote/remoteconfig.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/ui_remoteconfig.h
|
||||
scripting/python/pythonconsole.cpp
|
||||
scripting/python/pythonconsole.h
|
||||
scripting/python/pythonengine.cpp
|
||||
scripting/python/pythonengine.h
|
||||
scripting/python/pythonscript.cpp
|
||||
scripting/python/pythonscript.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/ui_pythonconsole.h
|
||||
ui/macsystemtrayicon.h
|
||||
ui/macsystemtrayicon.mm
|
||||
ui/wiimotedevshortcutsconfig.cpp
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/* This file is part of Clementine.
|
||||
Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
|
||||
Clementine 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Clementine is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Needs to be included first
|
||||
#include "pythonengine.h"
|
||||
|
||||
#include "pythonconsole.h"
|
||||
#include "ui_pythonconsole.h"
|
||||
|
||||
#include <gui/PythonQtScriptingConsole.h>
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QStandardItemModel>
|
||||
|
||||
PythonConsole::PythonConsole(QWidget *parent)
|
||||
: QWidget(parent),
|
||||
ui_(new Ui_PythonConsole),
|
||||
proxy_model_(new QSortFilterProxyModel(this)),
|
||||
engine_(NULL),
|
||||
widget_(NULL)
|
||||
{
|
||||
ui_->setupUi(this);
|
||||
connect(ui_->modules, SIGNAL(currentIndexChanged(int)), SLOT(ModuleChanged(int)));
|
||||
}
|
||||
|
||||
PythonConsole::~PythonConsole() {
|
||||
delete ui_;
|
||||
}
|
||||
|
||||
void PythonConsole::showEvent(QShowEvent* e) {
|
||||
engine_->EnsureInitialised();
|
||||
|
||||
QWidget::showEvent(e);
|
||||
}
|
||||
|
||||
void PythonConsole::SetEngine(PythonEngine* engine) {
|
||||
engine_ = engine;
|
||||
|
||||
proxy_model_->setSourceModel(engine->modules_model());
|
||||
proxy_model_->setDynamicSortFilter(true);
|
||||
|
||||
ui_->modules->setModel(proxy_model_);
|
||||
}
|
||||
|
||||
void PythonConsole::ModuleChanged(int row) {
|
||||
const QModelIndex index = proxy_model_->index(row, 0);
|
||||
|
||||
PythonQtObjectPtr ptr;
|
||||
ptr.fromVariant(index.data(Qt::UserRole + 1));
|
||||
|
||||
delete widget_;
|
||||
widget_ = new PythonQtScriptingConsole(this, ptr);
|
||||
|
||||
layout()->addWidget(widget_);
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/* This file is part of Clementine.
|
||||
Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
|
||||
Clementine 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Clementine is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PYTHONCONSOLE_H
|
||||
#define PYTHONCONSOLE_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
|
||||
class QSortFilterProxyModel;
|
||||
|
||||
class PythonQtScriptingConsole;
|
||||
|
||||
class PythonEngine;
|
||||
class Ui_PythonConsole;
|
||||
|
||||
class PythonConsole : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PythonConsole(QWidget* parent = 0);
|
||||
~PythonConsole();
|
||||
|
||||
void SetEngine(PythonEngine* engine);
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent* e);
|
||||
|
||||
private slots:
|
||||
void ModuleChanged(int row);
|
||||
|
||||
private:
|
||||
Ui_PythonConsole* ui_;
|
||||
QSortFilterProxyModel* proxy_model_;
|
||||
|
||||
PythonEngine* engine_;
|
||||
|
||||
PythonQtScriptingConsole* widget_;
|
||||
};
|
||||
|
||||
#endif // PYTHONCONSOLE_H
|
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>PythonConsole</class>
|
||||
<widget class="QWidget" name="PythonConsole">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>788</width>
|
||||
<height>439</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Context:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="modules">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -44,7 +44,8 @@ PythonEngine* PythonEngine::sInstance = NULL;
|
|||
|
||||
PythonEngine::PythonEngine(ScriptManager* manager)
|
||||
: LanguageEngine(manager),
|
||||
initialised_(false)
|
||||
initialised_(false),
|
||||
modules_model_(new QStandardItemModel(this))
|
||||
{
|
||||
Q_ASSERT(sInstance == NULL);
|
||||
sInstance = this;
|
||||
|
@ -57,6 +58,8 @@ PythonEngine::PythonEngine(ScriptManager* manager)
|
|||
PythonEngine::~PythonEngine() {
|
||||
sInstance = NULL;
|
||||
|
||||
modules_model_->clear();
|
||||
|
||||
scripts_module_ = PythonQtObjectPtr();
|
||||
clementine_module_ = PythonQtObjectPtr();
|
||||
PythonQt::cleanup();
|
||||
|
@ -105,6 +108,10 @@ bool PythonEngine::EnsureInitialised() {
|
|||
qLog(Debug) << "Creating scripts module";
|
||||
scripts_module_ = python_qt->createModuleFromScript(kScriptModulePrefix);
|
||||
|
||||
// The modules model contains all the modules
|
||||
modules_model_->clear();
|
||||
AddModuleToModel("__main__", python_qt->getMainModule());
|
||||
|
||||
qLog(Debug) << "Python initialisation complete";
|
||||
initialised_ = true;
|
||||
return true;
|
||||
|
@ -116,9 +123,10 @@ Script* PythonEngine::CreateScript(const ScriptInfo& info) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
Script* ret = new PythonScript(this, info);
|
||||
PythonScript* ret = new PythonScript(this, info);
|
||||
loaded_scripts_[ret->info().id()] = ret; // Used by RegisterNativeObject during startup
|
||||
if (ret->Init()) {
|
||||
AddModuleToModel(ret->module_name(), ret->module());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -127,6 +135,9 @@ Script* PythonEngine::CreateScript(const ScriptInfo& info) {
|
|||
}
|
||||
|
||||
void PythonEngine::DestroyScript(Script* script) {
|
||||
PythonScript* python_script = static_cast<PythonScript*>(script);
|
||||
RemoveModuleFromModel(python_script->module_name());
|
||||
|
||||
script->Unload();
|
||||
loaded_scripts_.remove(script->info().id());
|
||||
delete script;
|
||||
|
@ -139,3 +150,15 @@ void PythonEngine::PythonStdOut(const QString& str) {
|
|||
void PythonEngine::PythonStdErr(const QString& str) {
|
||||
manager()->AddLogLine("Python", str, true);
|
||||
}
|
||||
|
||||
void PythonEngine::AddModuleToModel(const QString& name, PythonQtObjectPtr ptr) {
|
||||
QStandardItem* item = new QStandardItem(name);
|
||||
item->setData(QVariant::fromValue(ptr));
|
||||
modules_model_->appendRow(item);
|
||||
}
|
||||
|
||||
void PythonEngine::RemoveModuleFromModel(const QString& name) {
|
||||
foreach (QStandardItem* item, modules_model_->findItems(name)) {
|
||||
modules_model_->removeRow(item->row());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
|
||||
#include "gtest/gtest_prod.h"
|
||||
|
||||
class QStandardItemModel;
|
||||
|
||||
|
||||
class PythonEngine : public LanguageEngine {
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -40,6 +43,7 @@ public:
|
|||
|
||||
ScriptInfo::Language language() const { return ScriptInfo::Language_Python; }
|
||||
QString name() const { return "python"; }
|
||||
QStandardItemModel* modules_model() const { return modules_model_; }
|
||||
|
||||
bool EnsureInitialised();
|
||||
|
||||
|
@ -50,6 +54,10 @@ private slots:
|
|||
void PythonStdOut(const QString& str);
|
||||
void PythonStdErr(const QString& str);
|
||||
|
||||
private:
|
||||
void AddModuleToModel(const QString& name, PythonQtObjectPtr ptr);
|
||||
void RemoveModuleFromModel(const QString& name);
|
||||
|
||||
private:
|
||||
static PythonEngine* sInstance;
|
||||
bool initialised_;
|
||||
|
@ -58,6 +66,7 @@ private:
|
|||
PythonQtObjectPtr scripts_module_;
|
||||
|
||||
QMap<QString, Script*> loaded_scripts_;
|
||||
QStandardItemModel* modules_model_;
|
||||
};
|
||||
|
||||
#endif // PYTHONENGINE_H
|
||||
|
|
|
@ -27,6 +27,9 @@ class PythonScript : public Script {
|
|||
public:
|
||||
PythonScript(PythonEngine* engine, const ScriptInfo& info);
|
||||
|
||||
const QString& module_name() const { return module_name_; }
|
||||
PythonQtObjectPtr module() const { return module_; }
|
||||
|
||||
bool Init();
|
||||
bool Unload();
|
||||
|
||||
|
@ -34,7 +37,6 @@ private:
|
|||
PythonEngine* engine_;
|
||||
|
||||
QString module_name_;
|
||||
|
||||
PythonQtObjectPtr module_;
|
||||
};
|
||||
|
||||
|
|
|
@ -16,6 +16,12 @@
|
|||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_SCRIPTING_PYTHON
|
||||
# include "scripting/python/pythonengine.h"
|
||||
# include "scripting/python/pythonconsole.h"
|
||||
#endif
|
||||
|
||||
#include "installscriptdialog.h"
|
||||
#include "scriptarchive.h"
|
||||
#include "scriptdialog.h"
|
||||
|
@ -155,6 +161,14 @@ void ScriptDialog::SetManager(ScriptManager* manager) {
|
|||
foreach (const QString& html, manager->log_lines()) {
|
||||
LogLineAdded(html);
|
||||
}
|
||||
|
||||
#ifdef HAVE_SCRIPTING_PYTHON
|
||||
// Add the python console
|
||||
PythonConsole* console = new PythonConsole(this);
|
||||
console->SetEngine(qobject_cast<PythonEngine*>(
|
||||
manager_->EngineForLanguage(ScriptInfo::Language_Python)));
|
||||
ui_->tab_widget->addTab(console, tr("Python console"));
|
||||
#endif
|
||||
}
|
||||
|
||||
void ScriptDialog::CurrentChanged(const QModelIndex& index) {
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
</size>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
|
|
|
@ -681,6 +681,9 @@ msgstr ""
|
|||
msgid "Constant bitrate"
|
||||
msgstr ""
|
||||
|
||||
msgid "Context:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Convert all music"
|
||||
msgstr "Converteer alle muziek"
|
||||
|
||||
|
@ -2116,6 +2119,9 @@ msgstr "druk op Wiiremote knop"
|
|||
msgid "Put songs in a random order"
|
||||
msgstr "Zet liedjes in willekeurige volgorde"
|
||||
|
||||
msgid "Python console"
|
||||
msgstr ""
|
||||
|
||||
msgid "Quality"
|
||||
msgstr "Kwaliteit"
|
||||
|
||||
|
|
Loading…
Reference in New Issue