Permalink
Browse files

Added support for executing JavaScript in the Console

Currently the actions you can perform here are still very limited.
There's the "tiled" module, which provides some simple properties,
access to the document manager (which isn't very usable yet) and a way
to trigger registered actions (and most global actions are now
registered).

Issue #949
  • Loading branch information...
bjorn committed Nov 23, 2018
1 parent 325c0ad commit 791ecf02458ebf30211a5bc9ed183de88e069161
@@ -38,7 +38,7 @@ class QString;
namespace Tiled {
/**
* An object to be added by classes that want to signal the debug console.
* An object to be added by classes that want to write to the Console view.
*/
class TILEDSHARED_EXPORT LoggingInterface : public QObject
{
@@ -124,7 +124,7 @@ void PythonPlugin::initialize()
PyRun_SimpleString(QString("import sys; sys.path.insert(0, \"%1\")")
.arg(mScriptDir).toUtf8().constData());
log(QString("-- Added %1 to path\n").arg(mScriptDir));
log(QString("Python scripts path: %1\n").arg(mScriptDir));
}
reloadModules();
@@ -60,5 +60,10 @@ QAction *ActionManager::action(Id id)
return act;
}
QAction *ActionManager::findAction(Id id)
{
return d->mIdToAction.value(id);
}
} // namespace Internal
} // namespace Tiled
@@ -42,6 +42,7 @@ class ActionManager : public QObject
static void registerAction(QAction *action, Id id);
static QAction *action(Id id);
static QAction *findAction(Id id);
signals:
void actionAdded(Id id);
@@ -154,7 +154,7 @@
<item row="4" column="0" colspan="3">
<widget class="QCheckBox" name="outputBox">
<property name="text">
<string>Show output in Debug Console</string>
<string>Show output in Console view</string>
</property>
</widget>
</item>
@@ -23,34 +23,50 @@
#include "commandmanager.h"
#include "logginginterface.h"
#include "pluginmanager.h"
#include "scriptmanager.h"
#include <QLineEdit>
#include <QPlainTextEdit>
#include <QShortcut>
#include <QVBoxLayout>
namespace Tiled {
namespace Internal {
ConsoleDock::ConsoleDock(QWidget *parent)
: QDockWidget(parent)
, mPlainTextEdit(new QPlainTextEdit)
, mLineEdit(new QLineEdit)
{
setObjectName(QLatin1String("ConsoleDock"));
setWindowTitle(tr("Debug Console"));
setWindowTitle(tr("Console"));
QWidget *widget = new QWidget(this);
QVBoxLayout *layout = new QVBoxLayout(widget);
layout->setMargin(0);
layout->setSpacing(0);
plainTextEdit = new QPlainTextEdit;
plainTextEdit->setReadOnly(true);
plainTextEdit->setStyleSheet(QString::fromUtf8(
mPlainTextEdit->setReadOnly(true);
mPlainTextEdit->setStyleSheet(QStringLiteral(
"QAbstractScrollArea {"
" background-color: black;"
" color:green;"
" color:lightgray;"
"}"
));
layout->addWidget(plainTextEdit);
mLineEdit->setPlaceholderText(tr("Execute script"));
mLineEdit->setClearButtonEnabled(true);
connect(mLineEdit, &QLineEdit::returnPressed,
this, &ConsoleDock::executeScript);
auto previousShortcut = new QShortcut(Qt::Key_Up, mLineEdit, nullptr, nullptr, Qt::WidgetShortcut);
connect(previousShortcut, &QShortcut::activated, [this] { moveHistory(-1); });
auto nextShortcut = new QShortcut(Qt::Key_Down, mLineEdit, nullptr, nullptr, Qt::WidgetShortcut);
connect(nextShortcut, &QShortcut::activated, [this] { moveHistory(1); });
layout->addWidget(mPlainTextEdit);
layout->addWidget(mLineEdit);
registerOutput(CommandManager::instance()->logger());
@@ -69,14 +85,20 @@ ConsoleDock::~ConsoleDock()
void ConsoleDock::appendInfo(const QString &str)
{
plainTextEdit->appendHtml(QLatin1String("<pre>") + str +
QLatin1String("</pre>"));
mPlainTextEdit->appendHtml(QLatin1String("<pre>") + str +
QLatin1String("</pre>"));
}
void ConsoleDock::appendError(const QString &str)
{
plainTextEdit->appendHtml(QLatin1String("<pre style='color:red'>") + str +
QLatin1String("</pre>"));
mPlainTextEdit->appendHtml(QLatin1String("<pre style='color:red'>") + str +
QLatin1String("</pre>"));
}
void ConsoleDock::appendScript(const QString &str)
{
mPlainTextEdit->appendHtml(QLatin1String("<pre style='color:lightgreen'>&gt; ") + str +
QLatin1String("</pre>"));
}
void ConsoleDock::onObjectAdded(QObject *object)
@@ -85,12 +107,54 @@ void ConsoleDock::onObjectAdded(QObject *object)
registerOutput(output);
}
void ConsoleDock::executeScript()
{
const QString script = mLineEdit->text();
if (script.isEmpty())
return;
appendScript(script);
const QJSValue result = ScriptManager::instance().evaluate(script);
if (result.isError()) {
QString errorString = result.toString();
// Add line number when script spanned multiple lines
if (script.indexOf(QLatin1Char('\n')) != -1) {
errorString = tr("At line %1: %2")
.arg(result.property(QStringLiteral("lineNumber")).toInt())
.arg(errorString);
}
appendError(errorString);
} else {
appendInfo(result.toString());
}
mLineEdit->clear();
mHistory.append(script);
mHistoryPosition = mHistory.size();
}
void ConsoleDock::moveHistory(int direction)
{
int newPosition = qBound(0, mHistoryPosition + direction, mHistory.size());
if (newPosition == mHistoryPosition)
return;
if (newPosition < mHistory.size())
mLineEdit->setText(mHistory.at(newPosition));
else
mLineEdit->clear();
mHistoryPosition = newPosition;
}
void ConsoleDock::registerOutput(LoggingInterface *output)
{
connect(output, &LoggingInterface::info,
this, &ConsoleDock::appendInfo);
connect(output, &LoggingInterface::error,
this, &ConsoleDock::appendError);
connect(output, &LoggingInterface::info, this, &ConsoleDock::appendInfo);
connect(output, &LoggingInterface::error, this, &ConsoleDock::appendError);
}
} // namespace Internal
@@ -21,7 +21,9 @@
#pragma once
#include <QDockWidget>
#include <QPlainTextEdit>
class QLineEdit;
class QPlainTextEdit;
namespace Tiled {
@@ -40,13 +42,20 @@ class ConsoleDock : public QDockWidget
private slots:
void appendInfo(const QString &str);
void appendError(const QString &str);
void appendScript(const QString &str);
void onObjectAdded(QObject *object);
void executeScript();
void moveHistory(int direction);
private:
void registerOutput(LoggingInterface *output);
QPlainTextEdit *plainTextEdit;
QPlainTextEdit *mPlainTextEdit;
QLineEdit *mLineEdit;
QVector<QString> mHistory;
int mHistoryPosition = 0;
};
} // namespace Internal
@@ -62,6 +62,8 @@ class DocumentManager : public QObject
{
Q_OBJECT
Q_PROPERTY(Document *currentDocument READ currentDocument NOTIFY currentDocumentChanged)
public:
static DocumentManager *instance();
static void deleteInstance();
@@ -59,8 +59,8 @@ MainToolBar::MainToolBar(QWidget *parent)
mSaveAction = new QAction(this);
QMenu *newMenu = new QMenu(this);
newMenu->addAction(ActionManager::action("file.new_map"));
newMenu->addAction(ActionManager::action("file.new_tileset"));
newMenu->addAction(ActionManager::action("NewMap"));
newMenu->addAction(ActionManager::action("NewTileset"));
mNewButton->setMenu(newMenu);
mNewButton->setPopupMode(QToolButton::InstantPopup);
@@ -203,8 +203,57 @@ MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags flags)
{
mUi->setupUi(this);
ActionManager::registerAction(mUi->actionNewMap, "file.new_map");
ActionManager::registerAction(mUi->actionNewTileset, "file.new_tileset");
ActionManager::registerAction(mUi->actionAbout, "About");
ActionManager::registerAction(mUi->actionAboutQt, "AboutQt");
ActionManager::registerAction(mUi->actionAddExternalTileset, "AddExternalTileset");
ActionManager::registerAction(mUi->actionAutoMap, "AutoMap");
ActionManager::registerAction(mUi->actionAutoMapWhileDrawing, "AutoMapWhileDrawing");
ActionManager::registerAction(mUi->actionBecomePatron, "BecomePatron");
ActionManager::registerAction(mUi->actionClearRecentFiles, "ClearRecentFiles");
ActionManager::registerAction(mUi->actionClearView, "ClearView");
ActionManager::registerAction(mUi->actionClose, "Close");
ActionManager::registerAction(mUi->actionCloseAll, "CloseAll");
ActionManager::registerAction(mUi->actionCopy, "Copy");
ActionManager::registerAction(mUi->actionCut, "Cut");
ActionManager::registerAction(mUi->actionDelete, "Delete");
ActionManager::registerAction(mUi->actionDocumentation, "Documentation");
ActionManager::registerAction(mUi->actionEditCommands, "EditCommands");
ActionManager::registerAction(mUi->actionExport, "Export");
ActionManager::registerAction(mUi->actionExportAs, "ExportAs");
ActionManager::registerAction(mUi->actionExportAsImage, "ExportAsImage");
ActionManager::registerAction(mUi->actionFullScreen, "FullScreen");
ActionManager::registerAction(mUi->actionHighlightCurrentLayer, "HighlightCurrentLayer");
ActionManager::registerAction(mUi->actionHighlightHoveredObject, "HighlightHoveredObject");
ActionManager::registerAction(mUi->actionLabelForHoveredObject, "LabelForHoveredObject");
ActionManager::registerAction(mUi->actionLabelsForAllObjects, "LabelsForAllObjects");
ActionManager::registerAction(mUi->actionLabelsForSelectedObjects, "LabelsForSelectedObjects");
ActionManager::registerAction(mUi->actionLoadWorld, "LoadWorld");
ActionManager::registerAction(mUi->actionMapProperties, "MapProperties");
ActionManager::registerAction(mUi->actionNewMap, "NewMap");
ActionManager::registerAction(mUi->actionNewTileset, "NewTileset");
ActionManager::registerAction(mUi->actionNoLabels, "NoLabels");
ActionManager::registerAction(mUi->actionOffsetMap, "OffsetMap");
ActionManager::registerAction(mUi->actionOpen, "Open");
ActionManager::registerAction(mUi->actionPaste, "Paste");
ActionManager::registerAction(mUi->actionPasteInPlace, "PasteInPlace");
ActionManager::registerAction(mUi->actionPreferences, "Preferences");
ActionManager::registerAction(mUi->actionQuit, "Quit");
ActionManager::registerAction(mUi->actionReload, "Reload");
ActionManager::registerAction(mUi->actionResizeMap, "ResizeMap");
ActionManager::registerAction(mUi->actionSave, "Save");
ActionManager::registerAction(mUi->actionSaveAll, "SaveAll");
ActionManager::registerAction(mUi->actionSaveAs, "SaveAs");
ActionManager::registerAction(mUi->actionShowGrid, "ShowGrid");
ActionManager::registerAction(mUi->actionShowTileAnimations, "ShowTileAnimations");
ActionManager::registerAction(mUi->actionShowTileObjectOutlines, "ShowTileObjectOutlines");
ActionManager::registerAction(mUi->actionSnapNothing, "SnapNothing");
ActionManager::registerAction(mUi->actionSnapToFineGrid, "SnapToFineGrid");
ActionManager::registerAction(mUi->actionSnapToGrid, "SnapToGrid");
ActionManager::registerAction(mUi->actionSnapToPixels, "SnapToPixels");
ActionManager::registerAction(mUi->actionTilesetProperties, "TilesetProperties");
ActionManager::registerAction(mUi->actionZoomIn, "ZoomIn");
ActionManager::registerAction(mUi->actionZoomNormal, "ZoomNormal");
ActionManager::registerAction(mUi->actionZoomOut, "ZoomOut");
auto *mapEditor = new MapEditor;
auto *tilesetEditor = new TilesetEditor;
@@ -21,6 +21,7 @@
#include "mapdocumentactionhandler.h"
#include "actionmanager.h"
#include "addremovelayer.h"
#include "addremovemapobject.h"
#include "changeselectedarea.h"
@@ -178,6 +179,34 @@ MapDocumentActionHandler::MapDocumentActionHandler(QObject *parent)
connect(mActionDuplicateObjects, &QAction::triggered, this, &MapDocumentActionHandler::duplicateObjects);
connect(mActionRemoveObjects, &QAction::triggered, this, &MapDocumentActionHandler::removeObjects);
ActionManager::registerAction(mActionSelectAll, "SelectAll");
ActionManager::registerAction(mActionSelectInverse, "SelectInverse");
ActionManager::registerAction(mActionSelectNone, "SelectNone");
ActionManager::registerAction(mActionCropToSelection, "CropToSelection");
ActionManager::registerAction(mActionAutocrop, "Autocrop");
ActionManager::registerAction(mActionAddTileLayer, "AddTileLayer");
ActionManager::registerAction(mActionAddObjectGroup, "AddObjectLayer");
ActionManager::registerAction(mActionAddImageLayer, "AddImageLayer");
ActionManager::registerAction(mActionAddGroupLayer, "AddGroupLayer");
ActionManager::registerAction(mActionLayerViaCopy, "LayerViaCopy");
ActionManager::registerAction(mActionLayerViaCut, "LayerViaCut");
ActionManager::registerAction(mActionGroupLayers, "GroupLayers");
ActionManager::registerAction(mActionUngroupLayers, "UngroupLayers");
ActionManager::registerAction(mActionDuplicateLayers, "DuplicateLayers");
ActionManager::registerAction(mActionMergeLayersDown, "MergeLayersDown");
ActionManager::registerAction(mActionSelectPreviousLayer, "SelectPreviousLayer");
ActionManager::registerAction(mActionSelectNextLayer, "SelectNextLayer");
ActionManager::registerAction(mActionRemoveLayers, "RemoveLayers");
ActionManager::registerAction(mActionMoveLayersUp, "MoveLayersUp");
ActionManager::registerAction(mActionMoveLayersDown, "MoveLayersDown");
ActionManager::registerAction(mActionToggleOtherLayers, "ToggleOtherLayers");
ActionManager::registerAction(mActionToggleLockOtherLayers, "ToggleLockOtherLayers");
ActionManager::registerAction(mActionLayerProperties, "LayerProperties");
ActionManager::registerAction(mActionDuplicateObjects, "DuplicateObjects");
ActionManager::registerAction(mActionRemoveObjects, "RemoveObjects");
updateActions();
retranslateUi();
}
@@ -59,12 +59,12 @@ void NoEditorWidget::changeEvent(QEvent *e)
void NoEditorWidget::newMap()
{
ActionManager::action("file.new_map")->trigger();
ActionManager::action("NewMap")->trigger();
}
void NoEditorWidget::newTileset()
{
ActionManager::action("file.new_tileset")->trigger();
ActionManager::action("NewTileset")->trigger();
}
void NoEditorWidget::openFile()
Oops, something went wrong.

0 comments on commit 791ecf0

Please sign in to comment.