mapeditor / mapeditor/tiled

Copy and Paste Objects Custom Properties in Plaintext

Open
#438 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C++
Stars
12.9k
Forks
2k
Avg merge
4h 27m
Merged PRs (30d)
8

Description

Sometimes (As it was my case) its easier to modify some properties on objects from within the game itself. So I needed a way to easily remerge the changes into the tmx. I added two options to the object context menu to get the object custom properties as plaintext and also to paste (merge) a list of plaintext properties from the clipboard to the object. The list is composed of lines ended with newline, with properties names and values interleaved. So now I can print the properties changes from my game and paste them directly to the desired object in the editor.

I don't know how to share the patch, so I'm pasting it here (I hope its ok):

0001-Adds-a-contextual-menu-to-objects-to-copy-and-paste-.patch
From 5a533ebaf103d0dd35d4ca345eb168f2d05d15a8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miguel=20=C3=81ngel=20P=C3=A9rez=20Mart=C3=ADnez?=
 <zlashmail@gmail.com>
Date: Wed, 15 May 2013 12:03:24 -0300
Subject: [PATCH] Adds a contextual menu to objects to copy and paste the
 properties set in plaintext to the clipboard.

---
 src/tiled/abstractobjecttool.cpp       |  4 ++++
 src/tiled/mapdocument.cpp              | 33 +++++++++++++++++++++++++++++++++
 src/tiled/mapdocument.h                |  3 +++
 src/tiled/mapdocumentactionhandler.cpp | 28 ++++++++++++++++++++++++++++
 src/tiled/mapdocumentactionhandler.h   | 10 ++++++++++
 5 files changed, 78 insertions(+)

diff --git a/src/tiled/abstractobjecttool.cpp b/src/tiled/abstractobjecttool.cpp
index 6f9ed5e..a5caf59 100644
--- a/src/tiled/abstractobjecttool.cpp
+++ b/src/tiled/abstractobjecttool.cpp
@@ -142,6 +142,10 @@ void AbstractObjectTool::showContextMenu(MapObjectItem *clickedObjectItem,
     menu.addAction(handler->actionRemoveObjects());

     menu.addSeparator();
+    menu.addAction(handler->actionCopyObjectCustomPlaintextProperties());
+    menu.addAction(handler->actionPasteObjectCustomPlaintextProperties());
+
+    menu.addSeparator();
     QAction *horizontalAction = menu.addAction(tr("Flip Horizontally"));
     QAction *verticalAction = menu.addAction(tr("Flip Vertically"));
     connect(horizontalAction, SIGNAL(triggered()), SLOT(flipHorizontally()));
diff --git a/src/tiled/mapdocument.cpp b/src/tiled/mapdocument.cpp
index 2d0f601..4238a85 100644
--- a/src/tiled/mapdocument.cpp
+++ b/src/tiled/mapdocument.cpp
@@ -55,6 +55,8 @@
 #include <QFileInfo>
 #include <QRect>
 #include <QUndoStack>
+#include <QApplication>
+#include <QClipboard>

 using namespace Tiled;
 using namespace Tiled::Internal;
@@ -695,6 +697,37 @@ void MapDocument::moveObjectsToGroup(const QList<MapObject *> &objects,
     mUndoStack->endMacro();
 }

+void MapDocument::copyObjectCustomPlaintextProperties(MapObject *object)
+{
+    QClipboard *clipboard = QApplication::clipboard();
+    QString clipboardStr = tr("");
+
+    QMapIterator<QString,QString> i(object->properties());
+    while (i.hasNext()) {
+        i.next();
+        clipboardStr+=i.key()+tr("\n")+i.value();
+        if(i.hasNext()) clipboardStr+=tr("\n");
+    }
+
+    clipboard->setText(clipboardStr);
+}
+
+void MapDocument::pasteObjectCustomPlaintextProperties(MapObject *object)
+{
+    QStringList clipboardList = QApplication::clipboard()->text().split(tr("\n"));
+    Properties propertiesFromClipboard;
+
+    for (int i = 0; i<clipboardList.size(); ++i)
+    {
+        QString key=clipboardList.at(i++);
+        if( i<clipboardList.size() ) propertiesFromClipboard[key]=clipboardList.at(i);
+    }
+
+    propertiesFromClipboard.merge(object->properties());
+
+    undoStack()->push(new ChangeProperties(this,tr("Object"),object,propertiesFromClipboard));
+}
+
 void MapDocument::setProperty(Object *object,
                               const QString &name,
                               const QString &value)
diff --git a/src/tiled/mapdocument.h b/src/tiled/mapdocument.h
index e4646bf..da83968 100644
--- a/src/tiled/mapdocument.h
+++ b/src/tiled/mapdocument.h
@@ -166,6 +166,9 @@ public:
     void moveObjectsToGroup(const QList<MapObject*> &objects,
                             ObjectGroup *objectGroup);

+    void copyObjectCustomPlaintextProperties(MapObject* object);
+    void pasteObjectCustomPlaintextProperties(MapObject *object);
+
     void setProperty(Object *object, const QString &name, const QString &value);
     void setProperties(Object *object, const Properties &properties);
     void removeProperty(Object *object, const QString &name);
diff --git a/src/tiled/mapdocumentactionhandler.cpp b/src/tiled/mapdocumentactionhandler.cpp
index fd75a4c..ddf2f06 100644
--- a/src/tiled/mapdocumentactionhandler.cpp
+++ b/src/tiled/mapdocumentactionhandler.cpp
@@ -96,6 +96,9 @@ MapDocumentActionHandler::MapDocumentActionHandler(QObject *parent)
     mActionRemoveObjects = new QAction(this);
     mActionRemoveObjects->setIcon(QIcon(QLatin1String(":/images/16x16/edit-delete.png")));

+    mActionCopyObjectCustomPlaintextProperties = new QAction(this);
+    mActionPasteObjectCustomPlaintextProperties = new QAction(this);
+
     Utils::setThemeIcon(mActionRemoveLayer, "edit-delete");
     Utils::setThemeIcon(mActionMoveLayerUp, "go-up");
     Utils::setThemeIcon(mActionMoveLayerDown, "go-down");
@@ -126,6 +129,9 @@ MapDocumentActionHandler::MapDocumentActionHandler(QObject *parent)
     connect(mActionDuplicateObjects, SIGNAL(triggered()), SLOT(duplicateObjects()));
     connect(mActionRemoveObjects, SIGNAL(triggered()), SLOT(removeObjects()));

+    connect(mActionCopyObjectCustomPlaintextProperties, SIGNAL(triggered()), SLOT(copyObjectCustomPlaintextProperties()));
+    connect(mActionPasteObjectCustomPlaintextProperties, SIGNAL(triggered()), SLOT(pasteObjectCustomPlaintextProperties()));
+
     updateActions();
     retranslateUi();
 }
@@ -151,6 +157,9 @@ void MapDocumentActionHandler::retranslateUi()
     mActionMoveLayerUp->setText(tr("R&aise Layer"));
     mActionMoveLayerDown->setText(tr("&Lower Layer"));
     mActionToggleOtherLayers->setText(tr("Show/&Hide all Other Layers"));
+
+    mActionCopyObjectCustomPlaintextProperties->setText(tr("Copy Plaintext Custom Properties"));
+    mActionPasteObjectCustomPlaintextProperties->setText(tr("Paste Plaintext Custom Properties"));
 }

 void MapDocumentActionHandler::setMapDocument(MapDocument *mapDocument)
@@ -326,6 +335,22 @@ void MapDocumentActionHandler::moveObjectsToGroup(ObjectGroup *objectGroup)
     }
 }

+void MapDocumentActionHandler::copyObjectCustomPlaintextProperties()
+{
+    if (mMapDocument) {
+        QList<MapObject*> selectedObjects = mMapDocument->selectedObjects();
+        if(selectedObjects.size()>0) mMapDocument->copyObjectCustomPlaintextProperties(selectedObjects[0]);
+    }
+}
+
+void MapDocumentActionHandler::pasteObjectCustomPlaintextProperties()
+{
+    if (mMapDocument) {
+        QList<MapObject*> selectedObjects = mMapDocument->selectedObjects();
+        if(selectedObjects.size()>0) mMapDocument->pasteObjectCustomPlaintextProperties(selectedObjects[0]);
+    }
+}
+
 void MapDocumentActionHandler::updateActions()
 {
     Map *map = 0;
@@ -370,6 +395,9 @@ void MapDocumentActionHandler::updateActions()
     mActionToggleOtherLayers->setEnabled(layerCount > 1);
     mActionRemoveLayer->setEnabled(currentLayerIndex >= 0);

+    mActionCopyObjectCustomPlaintextProperties->setEnabled(selectedObjectsCount == 1);
+    mActionPasteObjectCustomPlaintextProperties->setEnabled(selectedObjectsCount == 1);
+
     mActionDuplicateObjects->setEnabled(selectedObjectsCount > 0);
     mActionRemoveObjects->setEnabled(selectedObjectsCount > 0);

diff --git a/src/tiled/mapdocumentactionhandler.h b/src/tiled/mapdocumentactionhandler.h
index 81b76d1..bc6b808 100644
--- a/src/tiled/mapdocumentactionhandler.h
+++ b/src/tiled/mapdocumentactionhandler.h
@@ -75,6 +75,10 @@ public:
     QAction *actionRemoveObjects() const { return mActionRemoveObjects; }


+    QAction *actionCopyObjectCustomPlaintextProperties() const { return mActionCopyObjectCustomPlaintextProperties; }
+    QAction *actionPasteObjectCustomPlaintextProperties() const { return mActionPasteObjectCustomPlaintextProperties; }
+
+
 signals:
     void mapDocumentChanged(MapDocument *mapDocument);

@@ -102,6 +106,9 @@ public slots:
     void removeObjects();
     void moveObjectsToGroup(ObjectGroup *);

+    void copyObjectCustomPlaintextProperties();
+    void pasteObjectCustomPlaintextProperties();
+
 private slots:
     void updateActions();

@@ -127,6 +134,9 @@ private:
     QAction *mActionDuplicateObjects;
     QAction *mActionRemoveObjects;

+    QAction *mActionCopyObjectCustomPlaintextProperties;
+    QAction *mActionPasteObjectCustomPlaintextProperties;
+
     static MapDocumentActionHandler *mInstance;
 };

-- 
1.8.2.1

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the context-menu integration in src/tiled/abstractobjecttool.cpp and the actions in src/tiled/mapdocumentactionhandler.cpp/.h. Trace the clipboard and property handling in src/tiled/mapdocument.cpp/.h, including the existing ChangeProperties undo path. Done means a selected object can copy its custom properties as newline-separated plaintext and merge pasted properties back into the object.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
desktop
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.