예제 #1
0
void LayerModel::toggleOtherLayers(int layerIndex)
{
    if (mMap->layerCount() <= 1) // No other layers
        return;

    bool visibility = true;
    for (int i = 0; i < mMap->layerCount(); i++) {
        if (i == layerIndex)
            continue;

        Layer *layer = mMap->layerAt(i);
        if (layer->isVisible()) {
            visibility = false;
            break;
        }
    }

    QUndoStack *undoStack = mMapDocument->undoStack();
    if (visibility)
        undoStack->beginMacro(tr("Show Other Layers"));
    else
        undoStack->beginMacro(tr("Hide Other Layers"));

    for (int i = 0; i < mMap->layerCount(); i++) {
        if (i == layerIndex)
            continue;

        if (visibility != mMap->layerAt(i)->isVisible())
            undoStack->push(new SetLayerVisible(mMapDocument, i, visibility));
    }

    undoStack->endMacro();
}
예제 #2
0
void PropertiesDock::pasteProperties()
{
    auto clipboardManager = ClipboardManager::instance();

    Properties pastedProperties = clipboardManager->properties();
    if (pastedProperties.isEmpty())
        return;

    const QList<Object *> objects = mDocument->currentObjects();
    if (objects.isEmpty())
        return;

    QList<QUndoCommand*> commands;

    for (Object *object : objects) {
        Properties properties = object->properties();
        properties.merge(pastedProperties);

        if (object->properties() != properties) {
            commands.append(new ChangeProperties(mDocument, QString(), object,
                                                 properties));
        }
    }

    if (!commands.isEmpty()) {
        QUndoStack *undoStack = mDocument->undoStack();
        undoStack->beginMacro(tr("Paste Property/Properties", nullptr,
                                 pastedProperties.size()));

        for (QUndoCommand *command : commands)
            undoStack->push(command);

        undoStack->endMacro();
    }
}
예제 #3
0
void PropertyBrowser::applyImageLayerValue(PropertyId id, const QVariant &val)
{
    ImageLayer *imageLayer = static_cast<ImageLayer*>(mObject);
    QUndoStack *undoStack = mMapDocument->undoStack();

    switch (id) {
    case ImageSourceProperty: {
        const QString imageSource = val.toString();
        const QColor &color = imageLayer->transparentColor();
        undoStack->push(new ChangeImageLayerProperties(mMapDocument,
                                                       imageLayer,
                                                       color,
                                                       imageSource));
        break;
    }
    case ColorProperty: {
        QColor color = val.value<QColor>();
        if (color == Qt::gray)
            color = QColor();

        const QString &imageSource = imageLayer->imageSource();
        undoStack->push(new ChangeImageLayerProperties(mMapDocument,
                                                       imageLayer,
                                                       color,
                                                       imageSource));
        break;
    }
    default:
        break;
    }
}
예제 #4
0
void ButtonTaskMenu::createGroup()
{
    QDesignerFormWindowInterface *fw = formWindow();
    const ButtonList bl = buttonList(fw->cursor());
    // Do we need to remove the buttons from an existing group?
    QUndoCommand *removeCmd = 0;
    if (bl.front()->group()) {
        removeCmd = createRemoveButtonsCommand(fw, bl);
        if (!removeCmd)
            return;
    }
    // Add cmd
    CreateButtonGroupCommand *addCmd = new CreateButtonGroupCommand(fw);
    if (!addCmd->init(bl)) {
        qWarning("** WARNING Failed to initialize CreateButtonGroupCommand!");
        delete addCmd;
        return;
    }
    // Need a macro [even if we only have the add command] since the command might trigger additional commands
    QUndoStack *history = fw->commandHistory();
    history->beginMacro(addCmd->text());
    if (removeCmd)
        history->push(removeCmd);
    history->push(addCmd);
    history->endMacro();
}
예제 #5
0
void MapDocumentActionHandler::delete_()
{
    if (!mMapDocument)
        return;

    Layer *currentLayer = mMapDocument->currentLayer();
    if (!currentLayer)
        return;

    TileLayer *tileLayer = dynamic_cast<TileLayer*>(currentLayer);
    const QRegion &selectedArea = mMapDocument->selectedArea();
    const QList<MapObject*> &selectedObjects = mMapDocument->selectedObjects();

    QUndoStack *undoStack = mMapDocument->undoStack();
    undoStack->beginMacro(tr("Delete"));

    if (tileLayer && !selectedArea.isEmpty()) {
        undoStack->push(new EraseTiles(mMapDocument, tileLayer, selectedArea));
    } else if (!selectedObjects.isEmpty()) {
        foreach (MapObject *mapObject, selectedObjects)
            undoStack->push(new RemoveMapObject(mMapDocument, mapObject));
    }

    selectNone();
    undoStack->endMacro();
}
예제 #6
0
void EditPolygonTool::splitSegments()
{
    if (mSelectedHandles.size() < 2)
        return;

    const PointIndexesByObject p = groupIndexesByObject(mSelectedHandles);
    QMapIterator<MapObject*, RangeSet<int> > i(p);

    QUndoStack *undoStack = mapDocument()->undoStack();
    bool macroStarted = false;

    while (i.hasNext()) {
        MapObject *object = i.next().key();
        const RangeSet<int> &indexRanges = i.value();

        const bool closed = object->shape() == MapObject::Polygon;
        QPolygonF oldPolygon = object->polygon();
        QPolygonF newPolygon = splitPolygonSegments(oldPolygon, indexRanges,
                                                    closed);

        if (newPolygon.size() > oldPolygon.size()) {
            if (!macroStarted) {
                undoStack->beginMacro(tr("Split Segments"));
                macroStarted = true;
            }

            undoStack->push(new ChangePolygon(mapDocument(), object,
                                              newPolygon,
                                              oldPolygon));
        }
    }

    if (macroStarted)
        undoStack->endMacro();
}
예제 #7
0
void SCgMainWindow::initializeActions()
{
    QUndoStack* undoStack = mScene->undoStack();

    QAction* actionRedo = undoStack->createRedoAction(mScene);
    actionRedo->setShortcut(QKeySequence::Redo);
//    actionRedo->setShortcutContext(Qt::WidgetShortcut);

    QAction* actionUndo = undoStack->createUndoAction(mScene);
    actionUndo->setShortcut(QKeySequence::Undo);
//    actionUndo->setShortcutContext(Qt::WidgetShortcut);

    QAction* actionDelete = new QAction("Delete", mScene);
    actionDelete->setShortcut(QKeySequence::Delete);
    connect(actionDelete, SIGNAL(triggered()), mInputHandler, SLOT(deleteSelected()));
    actionDelete->setShortcutContext(Qt::WidgetShortcut);

    QAction* actionDeleteJustContour = new QAction("Delete just contour", mScene);
    actionDeleteJustContour->setShortcut( QKeySequence(tr("Backspace")) );
    connect(actionDeleteJustContour, SIGNAL(triggered()), mInputHandler, SLOT(deleteJustContour()));
    actionDeleteJustContour->setShortcutContext(Qt::WidgetShortcut);

    mView->addAction(actionDeleteJustContour);
    mView->addAction(actionDelete);
    mView->addAction(actionRedo);
    mView->addAction(actionUndo);
}
void ImageLayerPropertiesDialog::accept()
{
    QUndoStack *undoStack = mMapDocument->undoStack();

    const QColor newColor = mColorButton->color() != Qt::gray
        ? mColorButton->color()
        : QColor();

    const QString newPath = mImage->text();
    const bool localChanges = newColor != mImageLayer->transparentColor() ||
            newPath != mImageLayer->imageSource();

    if (localChanges) {
        undoStack->beginMacro(QCoreApplication::translate(
            "Undo Commands",
            "Change Image Layer Properties"));

        undoStack->push(new ChangeImageLayerProperties(
                            mMapDocument,
                            mImageLayer,
                            newColor,
                            newPath));
    }

    PropertiesDialog::accept();

    if (localChanges)
        undoStack->endMacro();
}
예제 #9
0
void eraseRegionObjectGroup(MapDocument *mapDocument,
                            ObjectGroup *layer,
                            const QRegion &where)
{
    QUndoStack *undo = mapDocument->undoStack();

    const auto objects = layer->objects();
    for (MapObject *obj : objects) {
        // TODO: we are checking bounds, which is only correct for rectangles and
        // tile objects. polygons and polylines are not covered correctly by this
        // erase method (we are in fact deleting too many objects)
        // TODO2: toAlignedRect may even break rects.

        // Convert the boundary of the object into tile space
        const QRectF objBounds = obj->boundsUseTile();
        QPointF tl = mapDocument->renderer()->pixelToTileCoords(objBounds.topLeft());
        QPointF tr = mapDocument->renderer()->pixelToTileCoords(objBounds.topRight());
        QPointF br = mapDocument->renderer()->pixelToTileCoords(objBounds.bottomRight());
        QPointF bl = mapDocument->renderer()->pixelToTileCoords(objBounds.bottomLeft());

        QRectF objInTileSpace;
        objInTileSpace.setTopLeft(tl);
        objInTileSpace.setTopRight(tr);
        objInTileSpace.setBottomRight(br);
        objInTileSpace.setBottomLeft(bl);

        const QRect objAlignedRect = objInTileSpace.toAlignedRect();
        if (where.intersects(objAlignedRect))
            undo->push(new RemoveMapObject(mapDocument, obj));
    }
}
예제 #10
0
void TilesetDock::embedTileset()
{
    Tileset *tileset = currentTileset();
    if (!tileset)
        return;

    if (!tileset->isExternal())
        return;

    // To embed a tileset we clone it, since further changes to that tileset
    // should not affect the exteral tileset.
    SharedTileset embeddedTileset = tileset->clone();

    QUndoStack *undoStack = mMapDocument->undoStack();
    int mapTilesetIndex = mMapDocument->map()->tilesets().indexOf(tileset->sharedPointer());

    // Tileset may not be part of the map yet
    if (mapTilesetIndex == -1)
        undoStack->push(new AddTileset(mMapDocument, embeddedTileset));
    else
        undoStack->push(new ReplaceTileset(mMapDocument, mapTilesetIndex, embeddedTileset));

    // Make sure the embedded tileset is selected
    int embeddedTilesetIndex = mTilesets.indexOf(embeddedTileset);
    if (embeddedTilesetIndex != -1)
        mTabBar->setCurrentIndex(embeddedTilesetIndex);
}
예제 #11
0
void PropertiesDock::removeProperties()
{
    Object *object = mDocument->currentObject();
    if (!object)
        return;

    const QList<QtBrowserItem*> items = mPropertyBrowser->selectedItems();
    if (items.isEmpty() || !mPropertyBrowser->allCustomPropertyItems(items))
        return;

    QStringList propertyNames;
    for (QtBrowserItem *item : items)
        propertyNames.append(item->property()->propertyName());

    QUndoStack *undoStack = mDocument->undoStack();
    undoStack->beginMacro(tr("Remove Property/Properties", nullptr,
                             propertyNames.size()));

    for (const QString &name : propertyNames) {
        undoStack->push(new RemoveProperty(mDocument,
                                           mDocument->currentObjects(),
                                           name));
    }

    undoStack->endMacro();
}
예제 #12
0
void MapPropertiesDialog::accept()
{
    int format = mLayerDataCombo->currentIndex();
    if (format == -1) {
        // this shouldn't happen!
        format = 0;
    }

    Map::LayerDataFormat newLayerDataFormat = static_cast<Map::LayerDataFormat>(format - 1);

    QUndoStack *undoStack = mMapDocument->undoStack();

    QColor newColor = mColorButton->color();
    if (newColor == Qt::darkGray)
        newColor = QColor();

    const Map *map = mMapDocument->map();
    bool localChanges = newColor != map->backgroundColor() ||
            newLayerDataFormat != map->layerDataFormat();

    if (localChanges) {
        undoStack->beginMacro(QCoreApplication::translate(
            "Undo Commands",
            "Change Map Properties"));

        undoStack->push(new ChangeMapProperties(mMapDocument,
                                                newColor,
                                                newLayerDataFormat));
    }

    PropertiesDialog::accept();

    if (localChanges)
        undoStack->endMacro();
}
예제 #13
0
void TilesetDock::swapTiles(Tile *tileA, Tile *tileB)
{
    if (!mMapDocument)
        return;

    QUndoStack *undoStack = mMapDocument->undoStack();
    undoStack->push(new SwapTiles(mMapDocument, tileA, tileB));
}
예제 #14
0
  void ReactionArrowTool::mousePressEvent(QGraphicsSceneMouseEvent *event)
  {
    QPointF downPos = event->buttonDownScenePos(event->button());
    QUndoStack *stack = scene()->stack();

    ReactionArrow *arrow = new ReactionArrow;
    stack->push(new AddItem(arrow, scene()));
    arrow->setPos(downPos);
  }
예제 #15
0
void RedoOperation::initialize(IServiceLocator *serviceLocator)
{
    QUndoStackAdapter* adapter = serviceLocator->locate<QUndoStackAdapter>();
    QUndoStack *stack = adapter->wrappedStack();

    m_action = stack->createRedoAction(this);
    setEnabled(m_action->isEnabled());

    connect(m_action, &QAction::changed, this, &RedoOperation::onActionChanged);
}
예제 #16
0
/**
 * Convenience method that deals with some of the logic related to pasting
 * a group of objects.
 */
void ClipboardManager::pasteObjectGroup(const ObjectGroup *objectGroup,
                                        MapDocument *mapDocument,
                                        const MapView *view,
                                        PasteFlags flags)
{
    Layer *currentLayer = mapDocument->currentLayer();
    if (!currentLayer)
        return;

    ObjectGroup *currentObjectGroup = currentLayer->asObjectGroup();
    if (!currentObjectGroup)
        return;

    QPointF insertPos;

    if (!(flags & PasteInPlace)) {
        // Determine where to insert the objects
        const MapRenderer *renderer = mapDocument->renderer();
        const QPointF center = objectGroup->objectsBoundingRect().center();

        // Take the mouse position if the mouse is on the view, otherwise
        // take the center of the view.
        QPoint viewPos;
        if (view->underMouse())
            viewPos = view->mapFromGlobal(QCursor::pos());
        else
            viewPos = QPoint(view->width() / 2, view->height() / 2);

        const QPointF scenePos = view->mapToScene(viewPos);

        insertPos = renderer->screenToPixelCoords(scenePos) - center;
        SnapHelper(renderer).snap(insertPos);
    }

    QUndoStack *undoStack = mapDocument->undoStack();
    QList<MapObject*> pastedObjects;
    pastedObjects.reserve(objectGroup->objectCount());

    undoStack->beginMacro(tr("Paste Objects"));
    for (const MapObject *mapObject : objectGroup->objects()) {
        if (flags & PasteNoTileObjects && !mapObject->cell().isEmpty())
            continue;

        MapObject *objectClone = mapObject->clone();
        objectClone->resetId();
        objectClone->setPosition(objectClone->position() + insertPos);
        pastedObjects.append(objectClone);
        undoStack->push(new AddMapObject(mapDocument,
                                         currentObjectGroup,
                                         objectClone));
    }
    undoStack->endMacro();

    mapDocument->setSelectedObjects(pastedObjects);
}
예제 #17
0
bool BookmarksModel::dropMimeData(const QMimeData *data,
                                  Qt::DropAction action, int row, int column, const QModelIndex &parent)
{
    if (action == Qt::IgnoreAction)
        return true;

    if (column > 0)
        return false;

    BookmarkNode *parentNode = node(parent);

    if (!data->hasFormat(MIMETYPE)) {
        if (!data->hasUrls())
            return false;

        BookmarkNode *node = new BookmarkNode(BookmarkNode::Bookmark, parentNode);
        node->url = QString::fromUtf8(data->urls().at(0).toEncoded());

        if (data->hasText())
            node->title = data->text();
        else
            node->title = node->url;

        m_bookmarksManager->addBookmark(parentNode, node, row);
        return true;
    }

    QByteArray ba = data->data(MIMETYPE);
    QDataStream stream(&ba, QIODevice::ReadOnly);
    if (stream.atEnd())
        return false;

    QUndoStack *undoStack = m_bookmarksManager->undoRedoStack();
    undoStack->beginMacro(QLatin1String("Move Bookmarks"));

    while (!stream.atEnd()) {
        QByteArray encodedData;
        stream >> encodedData;
        QBuffer buffer(&encodedData);
        buffer.open(QBuffer::ReadOnly);

        XbelReader reader;
        BookmarkNode *rootNode = reader.read(&buffer);
        QList<BookmarkNode*> children = rootNode->children();
        for (int i = 0; i < children.count(); ++i) {
            BookmarkNode *bookmarkNode = children.at(i);
            rootNode->remove(bookmarkNode);
            row = qMax(0, row);
            m_bookmarksManager->addBookmark(parentNode, bookmarkNode, row);
            m_endMacro = true;
        }
        delete rootNode;
    }
    return true;
}
예제 #18
0
void tst_QUndoGroup::addStackAndDie()
{
    // Test that QUndoStack doesn't keep a reference to QUndoGroup after the
    // group is deleted.
    QUndoStack *stack = new QUndoStack; 
    QUndoGroup *group = new QUndoGroup;
    group->addStack(stack);
    delete group;
    stack->setActive(true);
    delete stack;
}
예제 #19
0
void AbstractAspect::exec(QUndoCommand *cmd)
{
	Q_CHECK_PTR(cmd);
	QUndoStack *stack = undoStack();
	if (stack)
		stack->push(cmd);
	else {
		cmd->redo();
		delete cmd;
	}
}
예제 #20
0
void TilesetDock::removeTiles()
{
    TilesetView *view = currentTilesetView();
    if (!view)
        return;
    if (!view->selectionModel()->hasSelection())
        return;

    const QModelIndexList indexes = view->selectionModel()->selectedIndexes();
    const TilesetModel *model = view->tilesetModel();
    QList<Tile*> tiles;

    for (const QModelIndex &index : indexes)
        if (Tile *tile = model->tileAt(index))
            tiles.append(tile);

    auto matchesAnyTile = [&tiles] (const Cell &cell) {
        if (Tile *tile = cell.tile)
            return tiles.contains(tile);
        return false;
    };
    const bool inUse = hasTileReferences(mMapDocument, matchesAnyTile);

    // If the tileset is in use, warn the user and confirm removal
    if (inUse) {
        QMessageBox warning(QMessageBox::Warning,
                            tr("Remove Tiles"),
                            tr("One or more of the tiles to be removed are "
                               "still in use by the map!"),
                            QMessageBox::Yes | QMessageBox::No,
                            this);
        warning.setDefaultButton(QMessageBox::Yes);
        warning.setInformativeText(tr("Remove all references to these tiles?"));

        if (warning.exec() != QMessageBox::Yes)
            return;
    }

    QUndoStack *undoStack = mMapDocument->undoStack();
    undoStack->beginMacro(tr("Remove Tiles"));

    if (inUse)
        removeTileReferences(mMapDocument, matchesAnyTile);

    Tileset *tileset = view->tilesetModel()->tileset();
    undoStack->push(new RemoveTiles(mMapDocument, tileset, tiles));

    undoStack->endMacro();

    // Clear the current tiles, will be referencing the removed tiles
    setCurrentTiles(nullptr);
    setCurrentTile(nullptr);
}
예제 #21
0
void RaiseLowerHelper::push(const QList<QUndoCommand*> &commands,
                            const QString &text)
{
    if (commands.isEmpty())
        return;

    QUndoStack *undoStack = mMapDocument->undoStack();
    undoStack->beginMacro(text);
    foreach (QUndoCommand *command, commands)
        undoStack->push(command);
    undoStack->endMacro();
}
예제 #22
0
void PropertyBrowser::applyTerrainValue(PropertyId id, const QVariant &val)
{
    Terrain *terrain = static_cast<Terrain*>(mObject);

    if (id == NameProperty) {
        QUndoStack *undoStack = mMapDocument->undoStack();
        undoStack->push(new RenameTerrain(mMapDocument,
                                          terrain->tileset(),
                                          terrain->id(),
                                          val.toString()));
    }
}
예제 #23
0
void PropertiesDock::removeProperty()
{
    QtBrowserItem *item = mPropertyBrowser->currentItem();
    Object *object = mMapDocument->currentObject();
    if (!item || !object)
        return;

    const QString name = item->property()->propertyName();
    QUndoStack *undoStack = mMapDocument->undoStack();
    undoStack->push(new RemoveProperty(mMapDocument, mMapDocument->currentObjects(), name));

    // TODO: Would be nice to automatically select the next property
}
예제 #24
0
void TileCollisionDock::applyChanges()
{
    if (mSynchronizing)
        return;

    ObjectGroup *objectGroup = static_cast<ObjectGroup*>(mDummyMapDocument->map()->layerAt(1));
    ObjectGroup *clonedGroup = objectGroup->clone();

    QUndoStack *undoStack = mTilesetDocument->undoStack();
    mApplyingChanges = true;
    undoStack->push(new ChangeTileObjectGroup(mTilesetDocument, mTile, clonedGroup));
    mApplyingChanges = false;
}
예제 #25
0
void TilesetDock::changeSelectedMapObjectsTile(Tile *tile)
{
    if (!mMapDocument)
        return;

    // Only change tiles of tile objects
    QList<MapObject*> tileObjects = chooseTileObjects(mMapDocument->selectedObjects());

    if (tileObjects.isEmpty())
        return;

    QUndoStack *undoStack = mMapDocument->undoStack();
    undoStack->push(new ChangeMapObjectsTile(mMapDocument, tileObjects, tile));
}
예제 #26
0
void ButtonGroupMenu::breakGroup()
{
    BreakButtonGroupCommand *cmd = new BreakButtonGroupCommand(m_formWindow);
    if (cmd->init(m_buttonGroup)) {
        // Need a macro since the command might trigger additional commands
        QUndoStack *history = m_formWindow->commandHistory();
        history->beginMacro(cmd->text());
        history->push(cmd);
        history->endMacro();
    } else {
        qWarning("** WARNING Failed to initialize BreakButtonGroupCommand!");
        delete cmd;
    }
}
예제 #27
0
void CollectionListView::deleteCollection()
{
    int collectionId = MetadataEngine::getInstance().getCurrentCollectionId();

    if ((collectionId == 0) || SyncSession::IS_READ_ONLY) return; //0 stands for invalid

    //ask for confirmation
    QMessageBox box(QMessageBox::Question, tr("Delete Collection"),
                    tr("Are you sure you want to delete the selected collection?"
                       "<br><br><b>Warning:</b> This cannot be undone!"),
                    QMessageBox::Yes | QMessageBox::No,
                    this);
    box.setDefaultButton(QMessageBox::Yes);
    box.setWindowModality(Qt::WindowModal);
    int r = box.exec();
    if (r == QMessageBox::No) return;

    //check all fields for delete triggers
    CollectionFieldCleaner cleaner(this);
    cleaner.cleanCollection(collectionId);

    //delete metadata and tables
    MetadataEngine::getInstance().deleteCollection(collectionId);

    //delete from model
    m_model->removeRow(currentIndex().row());

    //delete settings about collection's column positions in TableView
    SettingsManager s;
    QString settingsKey = QString("collection_") + QString::number(collectionId);
    s.deleteObjectProperties(settingsKey);

    //reset cached id
    m_currentCollectionId = 0;

    //clear undo stack since this action is not undoable
    QUndoStack *stack = MainWindow::getUndoStack();
    if (stack) stack->clear();

    //set first collection as current one
    QModelIndex first = m_model->index(0, 1);
    if (first.isValid())
        setCurrentIndex(first);
    else
        MetadataEngine::getInstance().setCurrentCollectionId(0); //set invalid

    //set local data changed
    SyncSession::LOCAL_DATA_CHANGED = true;
}
예제 #28
0
void PropertiesDock::addProperty(const QString &name)
{
    if (name.isEmpty())
        return;
    Object *object = mMapDocument->currentObject();
    if (!object)
        return;

    if (!object->hasProperty(name)) {
        QUndoStack *undoStack = mMapDocument->undoStack();
        undoStack->push(new SetProperty(mMapDocument, mMapDocument->currentObjects(), name, QString()));
    }

    mPropertyBrowser->editCustomProperty(name);
}
예제 #29
0
void ObjectSelectionTool::keyPressed(QKeyEvent *event)
{
    if (mAction != NoAction) {
        event->ignore();
        return;
    }

    QPointF moveBy;

    switch (event->key()) {
    case Qt::Key_Up:    moveBy = QPointF(0, -1); break;
    case Qt::Key_Down:  moveBy = QPointF(0, 1); break;
    case Qt::Key_Left:  moveBy = QPointF(-1, 0); break;
    case Qt::Key_Right: moveBy = QPointF(1, 0); break;
    default:
        AbstractObjectTool::keyPressed(event);
        return;
    }

    const QSet<MapObjectItem*> &items = mapScene()->selectedObjectItems();
    const Qt::KeyboardModifiers modifiers = event->modifiers();

    if (moveBy.isNull() || items.isEmpty() || (modifiers & Qt::ControlModifier)) {
        event->ignore();
        return;
    }

    const bool moveFast = modifiers & Qt::ShiftModifier;
    const bool snapToFineGrid = Preferences::instance()->snapToFineGrid();

    if (moveFast) {
        // TODO: This only makes sense for orthogonal maps
        moveBy.rx() *= mapDocument()->map()->tileWidth();
        moveBy.ry() *= mapDocument()->map()->tileHeight();
        if (snapToFineGrid)
            moveBy /= Preferences::instance()->gridFine();
    }

    QUndoStack *undoStack = mapDocument()->undoStack();
    undoStack->beginMacro(tr("Move %n Object(s)", "", items.size()));
    int i = 0;
    foreach (MapObjectItem *objectItem, items) {
        MapObject *object = objectItem->mapObject();
        const QPointF oldPos = object->position();
        const QPointF newPos = oldPos + moveBy;
        undoStack->push(new MoveMapObject(mapDocument(), object, newPos, oldPos));
        ++i;
    }
예제 #30
0
void PropertiesDock::renameProperty(const QString &name)
{
    if (name.isEmpty())
        return;

    QtBrowserItem *item = mPropertyBrowser->currentItem();
    if (!item)
        return;

    const QString oldName = item->property()->propertyName();
    if (oldName == name)
        return;

    QUndoStack *undoStack = mMapDocument->undoStack();
    undoStack->push(new RenameProperty(mMapDocument, mMapDocument->currentObjects(), oldName, name));
}