Skip to content
Permalink
Browse files

Made the shortcuts for the tools configurable

With the implementation being not exactly trivial this is really a new
feature, but I'm including it in Tiled 1.3 anyway since it really should
have been included in the initial release.

Closes #2666
  • Loading branch information
bjorn committed Nov 19, 2019
1 parent 74eb723 commit ce798fbb558d4bca53ba8a6a4db87012f7f2429d
Showing with 196 additions and 117 deletions.
  1. +3 −2 src/tiled/abstractobjecttool.cpp
  2. +2 −1 src/tiled/abstractobjecttool.h
  3. +3 −2 src/tiled/abstracttilefilltool.cpp
  4. +2 −1 src/tiled/abstracttilefilltool.h
  5. +3 −2 src/tiled/abstracttileselectiontool.cpp
  6. +2 −1 src/tiled/abstracttileselectiontool.h
  7. +3 −2 src/tiled/abstracttiletool.cpp
  8. +2 −1 src/tiled/abstracttiletool.h
  9. +6 −2 src/tiled/abstracttool.cpp
  10. +18 −1 src/tiled/abstracttool.h
  11. +23 −15 src/tiled/actionmanager.cpp
  12. +1 −1 src/tiled/actionmanager.h
  13. +2 −1 src/tiled/bucketfilltool.cpp
  14. +2 −1 src/tiled/createellipseobjecttool.cpp
  15. +3 −2 src/tiled/createobjecttool.cpp
  16. +1 −1 src/tiled/createobjecttool.h
  17. +1 −1 src/tiled/createpointobjecttool.cpp
  18. +1 −1 src/tiled/createpolygonobjecttool.cpp
  19. +1 −1 src/tiled/createrectangleobjecttool.cpp
  20. +2 −2 src/tiled/createscalableobjecttool.cpp
  21. +1 −1 src/tiled/createscalableobjecttool.h
  22. +1 −1 src/tiled/createtemplatetool.cpp
  23. +1 −1 src/tiled/createtextobjecttool.cpp
  24. +1 −1 src/tiled/createtileobjecttool.cpp
  25. +5 −4 src/tiled/editpolygontool.cpp
  26. +2 −1 src/tiled/eraser.cpp
  27. +2 −1 src/tiled/layeroffsettool.cpp
  28. +2 −1 src/tiled/magicwandtool.cpp
  29. +5 −4 src/tiled/objectselectiontool.cpp
  30. +1 −1 src/tiled/scriptedaction.h
  31. +2 −2 src/tiled/scriptedtool.cpp
  32. +1 −1 src/tiled/scriptedtool.h
  33. +7 −6 src/tiled/scriptmodule.cpp
  34. +2 −2 src/tiled/scriptmodule.h
  35. +2 −1 src/tiled/selectsametiletool.cpp
  36. +2 −1 src/tiled/shapefilltool.cpp
  37. +2 −1 src/tiled/stampbrush.cpp
  38. +3 −1 src/tiled/templatesdock.cpp
  39. +2 −1 src/tiled/terrainbrush.cpp
  40. +2 −1 src/tiled/tileselectiontool.cpp
  41. +49 −29 src/tiled/toolmanager.cpp
  42. +13 −8 src/tiled/toolmanager.h
  43. +7 −6 src/tiled/wangbrush.cpp
@@ -78,11 +78,12 @@ static bool isChangedTemplateInstance(MapObject *mapObject)
}


AbstractObjectTool::AbstractObjectTool(const QString &name,
AbstractObjectTool::AbstractObjectTool(Id id,
const QString &name,
const QIcon &icon,
const QKeySequence &shortcut,
QObject *parent)
: AbstractTool(name, icon, shortcut, parent)
: AbstractTool(id, name, icon, shortcut, parent)
, mMapScene(nullptr)
{
QIcon flipHorizontalIcon(QLatin1String(":images/24/flip-horizontal.png"));
@@ -44,7 +44,8 @@ class AbstractObjectTool : public AbstractTool
/**
* Constructs an abstract object tool with the given \a name and \a icon.
*/
AbstractObjectTool(const QString &name,
AbstractObjectTool(Id id,
const QString &name,
const QIcon &icon,
const QKeySequence &shortcut,
QObject *parent = nullptr);
@@ -29,12 +29,13 @@

using namespace Tiled;

AbstractTileFillTool::AbstractTileFillTool(const QString &name,
AbstractTileFillTool::AbstractTileFillTool(Id id,
const QString &name,
const QIcon &icon,
const QKeySequence &shortcut,
BrushItem *brushItem,
QObject *parent)
: AbstractTileTool(name, icon, shortcut, brushItem, parent)
: AbstractTileTool(id, name, icon, shortcut, brushItem, parent)
, mFillMethod(TileFill)
, mStampActions(new StampActions(this))
, mWangSet(nullptr)
@@ -46,7 +46,8 @@ class AbstractTileFillTool : public AbstractTileTool
WangFill
};

AbstractTileFillTool(const QString &name,
AbstractTileFillTool(Id id,
const QString &name,
const QIcon &icon,
const QKeySequence &shortcut,
BrushItem *brushItem = nullptr,
@@ -31,11 +31,12 @@

using namespace Tiled;

AbstractTileSelectionTool::AbstractTileSelectionTool(const QString &name,
AbstractTileSelectionTool::AbstractTileSelectionTool(Id id,
const QString &name,
const QIcon &icon,
const QKeySequence &shortcut,
QObject *parent)
: AbstractTileTool(name, icon, shortcut, nullptr, parent)
: AbstractTileTool(id, name, icon, shortcut, nullptr, parent)
, mSelectionMode(Replace)
, mDefaultMode(Replace)
{
@@ -35,7 +35,8 @@ class AbstractTileSelectionTool : public AbstractTileTool
Q_OBJECT

public:
AbstractTileSelectionTool(const QString &name,
AbstractTileSelectionTool(Id id,
const QString &name,
const QIcon &icon,
const QKeySequence &shortcut,
QObject *parent = nullptr);
@@ -34,12 +34,13 @@

using namespace Tiled;

AbstractTileTool::AbstractTileTool(const QString &name,
AbstractTileTool::AbstractTileTool(Id id,
const QString &name,
const QIcon &icon,
const QKeySequence &shortcut,
BrushItem *brushItem,
QObject *parent)
: AbstractTool(name, icon, shortcut, parent)
: AbstractTool(id, name, icon, shortcut, parent)
, mTilePositionMethod(OnTiles)
, mBrushItem(brushItem)
, mBrushVisible(false)
@@ -44,7 +44,8 @@ class AbstractTileTool : public AbstractTool
/**
* Constructs an abstract tile tool with the given \a name and \a icon.
*/
AbstractTileTool(const QString &name,
AbstractTileTool(Id id,
const QString &name,
const QIcon &icon,
const QKeySequence &shortcut,
BrushItem *brushItem = nullptr,
@@ -28,9 +28,13 @@

namespace Tiled {

AbstractTool::AbstractTool(const QString &name, const QIcon &icon,
const QKeySequence &shortcut, QObject *parent)
AbstractTool::AbstractTool(Id id,
const QString &name,
const QIcon &icon,
const QKeySequence &shortcut,
QObject *parent)
: QObject(parent)
, mId(id)
, mName(name)
, mIcon(icon)
, mShortcut(shortcut)
@@ -22,6 +22,7 @@
#pragma once

#include "changeevents.h"
#include "id.h"

#include <QCursor>
#include <QGraphicsSceneMouseEvent>
@@ -58,6 +59,7 @@ class AbstractTool : public QObject
{
Q_OBJECT

Q_PROPERTY(QByteArray id READ idName CONSTANT)
Q_PROPERTY(QString name READ name WRITE setName NOTIFY changed)
Q_PROPERTY(QIcon icon READ icon WRITE setIcon NOTIFY changed)
Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut NOTIFY changed)
@@ -69,11 +71,15 @@ class AbstractTool : public QObject
/**
* Constructs an abstract tool with the given \a name and \a icon.
*/
AbstractTool(const QString &name,
AbstractTool(Id id,
const QString &name,
const QIcon &icon,
const QKeySequence &shortcut,
QObject *parent = nullptr);

Id id() const;
QByteArray idName() const;

QString name() const;
void setName(const QString &name);

@@ -201,13 +207,24 @@ class AbstractTool : public QObject
QKeySequence mShortcut;
QString mStatusInfo;
QCursor mCursor;
Id mId;
bool mEnabled;

ToolManager *mToolManager;
MapDocument *mMapDocument;
};


inline Id AbstractTool::id() const
{
return mId;
}

inline QByteArray AbstractTool::idName() const
{
return mId.name();
}

inline QString AbstractTool::name() const
{
return mName;
@@ -31,7 +31,7 @@ namespace Tiled {
class ActionManagerPrivate
{
public:
QHash<Id, QAction*> mIdToAction;
QMultiHash<Id, QAction*> mIdToActions;
QHash<Id, QMenu*> mIdToMenu;

QHash<Id, QKeySequence> mDefaultShortcuts; // for resetting to default
@@ -92,8 +92,8 @@ ActionManager *ActionManager::instance()

void ActionManager::registerAction(QAction *action, Id id)
{
Q_ASSERT_X(!d->mIdToAction.contains(id), "ActionManager::registerAction", "duplicate id");
d->mIdToAction.insert(id, action);
Q_ASSERT_X(!d->mIdToActions.contains(id, action), "ActionManager::registerAction", "duplicate action");
d->mIdToActions.insert(id, action);
d->mLastKnownShortcuts.insert(id, action->shortcut());

connect(action, &QAction::changed, m_instance, [id,action] {
@@ -121,10 +121,10 @@ void ActionManager::registerAction(QAction *action, Id id)
emit m_instance->actionsChanged();
}

void ActionManager::unregisterAction(Id id)
void ActionManager::unregisterAction(QAction *action, Id id)
{
Q_ASSERT_X(d->mIdToAction.contains(id), "ActionManager::unregisterAction", "unknown id");
QAction *action = d->mIdToAction.take(id);
Q_ASSERT_X(d->mIdToActions.contains(id, action), "ActionManager::unregisterAction", "unknown action");
d->mIdToActions.remove(id, action);
action->disconnect(m_instance);
d->mDefaultShortcuts.remove(id);
d->mLastKnownShortcuts.remove(id);
@@ -145,14 +145,14 @@ void ActionManager::unregisterMenu(Id id)

QAction *ActionManager::action(Id id)
{
auto action = d->mIdToAction.value(id);
auto action = d->mIdToActions.value(id);
Q_ASSERT_X(action, "ActionManager::action", "unknown id");
return action;
}

QAction *ActionManager::findAction(Id id)
{
return d->mIdToAction.value(id);
return d->mIdToActions.value(id);
}

QMenu *ActionManager::menu(Id id)
@@ -169,7 +169,7 @@ QMenu *ActionManager::findMenu(Id id)

QList<Id> ActionManager::actions()
{
return d->mIdToAction.keys();
return d->mIdToActions.uniqueKeys();
}

QList<Id> ActionManager::menus()
@@ -181,13 +181,16 @@ void ActionManager::setCustomShortcut(Id id, const QKeySequence &keySequence)
{
Q_ASSERT(!d->mResettingShortcut);

auto a = action(id);
const auto actions = d->mIdToActions.values(id);
Q_ASSERT_X(!actions.isEmpty(), "ActionManager::setCustomShortcut", "unknown id");

if (!hasCustomShortcut(id))
d->mDefaultShortcuts.insert(id, a->shortcut());
d->mDefaultShortcuts.insert(id, actions.first()->shortcut());

d->mCustomShortcuts.insert(id, keySequence);
applyShortcut(a, keySequence);

for (QAction *a : actions)
applyShortcut(a, keySequence);

auto settings = Preferences::instance()->settings();
settings->setValue(QLatin1String("CustomShortcuts/") + id.toString(),
@@ -204,10 +207,14 @@ void ActionManager::resetCustomShortcut(Id id)
if (!hasCustomShortcut(id))
return;

const auto actions = d->mIdToActions.values(id);
Q_ASSERT_X(!actions.isEmpty(), "ActionManager::resetCustomShortcut", "unknown id");

d->mResettingShortcut = true;

auto a = action(id);
applyShortcut(a, d->mDefaultShortcuts.take(id));
const QKeySequence defaultShortcut = d->mDefaultShortcuts.take(id);
for (QAction *a : actions)
applyShortcut(a, defaultShortcut);
d->mCustomShortcuts.remove(id);

d->mResettingShortcut = false;
@@ -221,7 +228,8 @@ void ActionManager::resetAllCustomShortcuts()
QHashIterator<Id, QKeySequence> iterator(d->mDefaultShortcuts);
while (iterator.hasNext()) {
iterator.next();
if (auto a = findAction(iterator.key()))
const auto actions = d->mIdToActions.values(iterator.key());
for (QAction *a : actions)
applyShortcut(a, iterator.value());
}
d->mDefaultShortcuts.clear();
@@ -42,7 +42,7 @@ class ActionManager : public QObject
static ActionManager *instance();

static void registerAction(QAction *action, Id id);
static void unregisterAction(Id id);
static void unregisterAction(QAction *action, Id id);

static void registerMenu(QMenu *menu, Id id);
static void unregisterMenu(Id id);
@@ -40,7 +40,8 @@
using namespace Tiled;

BucketFillTool::BucketFillTool(QObject *parent)
: AbstractTileFillTool(tr("Bucket Fill Tool"),
: AbstractTileFillTool("BucketFillTool",
tr("Bucket Fill Tool"),
QIcon(QLatin1String(
":images/22/stock-tool-bucket-fill.png")),
QKeySequence(Qt::Key_F),
@@ -26,7 +26,8 @@
using namespace Tiled;

CreateEllipseObjectTool::CreateEllipseObjectTool(QObject *parent)
: CreateScalableObjectTool(parent)
: CreateScalableObjectTool("CreateEllipseObjectTool",
parent)
{
QIcon icon(QLatin1String(":images/24/insert-ellipse.png"));
icon.addFile(QLatin1String(":images/48/insert-ellipse.png"));
@@ -42,8 +42,9 @@

using namespace Tiled;

CreateObjectTool::CreateObjectTool(QObject *parent)
: AbstractObjectTool(QString(),
CreateObjectTool::CreateObjectTool(Id id, QObject *parent)
: AbstractObjectTool(id,
QString(),
QIcon(),
QKeySequence(),
parent)
@@ -36,7 +36,7 @@ class CreateObjectTool : public AbstractObjectTool
Q_OBJECT

public:
CreateObjectTool(QObject *parent = nullptr);
CreateObjectTool(Id id, QObject *parent = nullptr);
~CreateObjectTool() override;

void activate(MapScene *scene) override;
@@ -30,7 +30,7 @@
using namespace Tiled;

CreatePointObjectTool::CreatePointObjectTool(QObject *parent)
: CreateObjectTool(parent)
: CreateObjectTool("CreatePointObjectTool", parent)
{
QIcon icon(QLatin1String(":images/24/insert-point.png"));
icon.addFile(QLatin1String(":images/48/insert-point.png"));
@@ -48,7 +48,7 @@
using namespace Tiled;

CreatePolygonObjectTool::CreatePolygonObjectTool(QObject *parent)
: CreateObjectTool(parent)
: CreateObjectTool("CreatePolygonObjectTool", parent)
, mOverlayPolygonObject(new MapObject)
, mOverlayObjectGroup(new ObjectGroup)
, mOverlayPolygonItem(nullptr)
@@ -26,7 +26,7 @@
using namespace Tiled;

CreateRectangleObjectTool::CreateRectangleObjectTool(QObject *parent)
: CreateScalableObjectTool(parent)
: CreateScalableObjectTool("CreateRectangleObjectTool", parent)
{
QIcon icon(QLatin1String(":images/24/insert-rectangle.png"));
icon.addFile(QLatin1String(":images/48/insert-rectangle.png"));
@@ -29,8 +29,8 @@

using namespace Tiled;

CreateScalableObjectTool::CreateScalableObjectTool(QObject *parent)
: CreateObjectTool(parent)
CreateScalableObjectTool::CreateScalableObjectTool(Id id, QObject *parent)
: CreateObjectTool(id, parent)
{
}

@@ -29,7 +29,7 @@ class CreateScalableObjectTool : public CreateObjectTool
Q_OBJECT

public:
CreateScalableObjectTool(QObject *parent);
CreateScalableObjectTool(Id id, QObject *parent);

protected:
bool startNewMapObject(const QPointF &pos, ObjectGroup *objectGroup) override;
@@ -32,7 +32,7 @@
using namespace Tiled;

CreateTemplateTool::CreateTemplateTool(QObject *parent)
: CreateObjectTool(parent)
: CreateObjectTool("CreateTemplateTool", parent)
{
QIcon icon(QLatin1String(":images/24/insert-template.png"));
icon.addFile(QLatin1String(":images/48/insert-template.png"));
@@ -30,7 +30,7 @@
namespace Tiled {

CreateTextObjectTool::CreateTextObjectTool(QObject *parent)
: CreateObjectTool(parent)
: CreateObjectTool("CreateTextObjectTool", parent)
{
QIcon icon(QLatin1String(":images/24/insert-text.png"));
icon.addFile(QLatin1String(":images/48/insert-text.png"));

0 comments on commit ce798fb

Please sign in to comment.
You can’t perform that action at this time.