movetool.cpp 11.8 KB
Newer Older
hjk's avatar
hjk committed
1
/****************************************************************************
2
**
3 4
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
5
**
hjk's avatar
hjk committed
6
** This file is part of Qt Creator.
7
**
hjk's avatar
hjk committed
8 9 10 11
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
12 13 14
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
15
**
16 17
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
18 19 20 21 22
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
con's avatar
con committed
23
**
hjk's avatar
hjk committed
24
****************************************************************************/
25 26 27 28 29

#include "movetool.h"

#include "formeditorscene.h"
#include "formeditorview.h"
30
#include "formeditorwidget.h"
31
#include "formeditorgraphicsview.h"
32 33 34 35 36

#include "resizehandleitem.h"

#include <QApplication>
#include <QGraphicsSceneMouseEvent>
37
#include <QAction>
hjk's avatar
hjk committed
38
#include <QDebug>
39 40 41 42 43 44 45

namespace QmlDesigner {

MoveTool::MoveTool(FormEditorView *editorView)
    : AbstractFormEditorTool(editorView),
    m_moveManipulator(editorView->scene()->manipulatorLayerItem(), editorView),
    m_selectionIndicator(editorView->scene()->manipulatorLayerItem()),
Marco Bubke's avatar
Marco Bubke committed
46
    m_resizeIndicator(editorView->scene()->manipulatorLayerItem()),
47
    m_anchorIndicator(editorView->scene()->manipulatorLayerItem()),
48 49
    m_bindingIndicator(editorView->scene()->manipulatorLayerItem()),
    m_contentNotEditableIndicator(editorView->scene()->manipulatorLayerItem())
50
{
51
    m_selectionIndicator.setCursor(Qt::SizeAllCursor);
52 53 54 55 56 57 58 59 60 61 62 63 64
}

MoveTool::~MoveTool()
{

}

void MoveTool::clear()
{
    m_moveManipulator.clear();
    m_movingItems.clear();
    m_selectionIndicator.clear();
    m_resizeIndicator.clear();
Marco Bubke's avatar
Marco Bubke committed
65
    m_anchorIndicator.clear();
66
    m_bindingIndicator.clear();
67
    m_contentNotEditableIndicator.clear();
68 69

    AbstractFormEditorTool::clear();
70 71 72 73 74 75
    view()->formEditorWidget()->graphicsView()->viewport()->unsetCursor();
}

void MoveTool::start()
{
    view()->formEditorWidget()->graphicsView()->viewport()->setCursor(Qt::SizeAllCursor);
76 77 78 79 80
}

void MoveTool::mousePressEvent(const QList<QGraphicsItem*> &itemList,
                                            QGraphicsSceneMouseEvent *event)
{
81 82 83 84 85 86 87 88 89 90
    if (event->button() == Qt::LeftButton) {
        if (itemList.isEmpty())
            return;
        m_movingItems = movingItems(items());
        if (m_movingItems.isEmpty())
            return;

        m_moveManipulator.setItems(m_movingItems);
        m_moveManipulator.begin(event->scenePos());
    }
91

92
    AbstractFormEditorTool::mousePressEvent(itemList, event);
93 94 95 96 97
}

void MoveTool::mouseMoveEvent(const QList<QGraphicsItem*> &itemList,
                                           QGraphicsSceneMouseEvent *event)
{
98 99 100
    if (m_moveManipulator.isActive()) {
        if (m_movingItems.isEmpty())
            return;
101

102 103
        //    m_selectionIndicator.hide();
        m_resizeIndicator.hide();
Marco Bubke's avatar
Marco Bubke committed
104
        m_anchorIndicator.hide();
105
        m_bindingIndicator.hide();
106

107
        FormEditorItem *containerItem = containerFormEditorItem(itemList, m_movingItems);
108
        if (containerItem && view()->currentState().isBaseState()) {
109 110
            if (containerItem != m_movingItems.first()->parentItem()
                    && event->modifiers().testFlag(Qt::ShiftModifier)) {
111 112 113 114 115

                FormEditorItem *movingItem = m_movingItems.first();

                if (m_movingItems.count() > 1
                        || (movingItem->qmlItemNode().canBereparentedTo(containerItem->qmlItemNode())))
116
                        m_moveManipulator.reparentTo(containerItem, MoveManipulator::EnforceReparent);
117
            }
118
        }
119

120
        m_moveManipulator.update(event->scenePos(), generateUseSnapping(event->modifiers()));
121
    }
122 123 124
}

void MoveTool::hoverMoveEvent(const QList<QGraphicsItem*> &itemList,
125
                        QGraphicsSceneMouseEvent * event)
126
{
Thomas Hartmann's avatar
Thomas Hartmann committed
127 128 129 130 131
    if (itemList.isEmpty()) {
        view()->changeToSelectionTool();
        return;
    }

132 133 134 135 136 137
    ResizeHandleItem* resizeHandle = ResizeHandleItem::fromGraphicsItem(itemList.first());
    if (resizeHandle) {
        view()->changeToResizeTool();
        return;
    }

138 139 140
    if (view()->hasSingleSelectedModelNode() && selectedItemCursorInMovableArea(event->scenePos()))
        return;

141 142 143 144
    if (!topSelectedItemIsMovable(itemList)) {
        view()->changeToSelectionTool();
        return;
    }
145

146
    if (view()->hasSingleSelectedModelNode()) {
147 148 149 150 151 152 153 154 155 156 157
        view()->changeToSelectionTool();
        return;
    }

    if (event->modifiers().testFlag(Qt::ShiftModifier)
            || event->modifiers().testFlag(Qt::ControlModifier) ) {
        view()->changeToSelectionTool();
        return;
    }


158
    m_contentNotEditableIndicator.setItems(toFormEditorItemList(itemList));
159 160 161 162
}

void MoveTool::keyPressEvent(QKeyEvent *event)
{
163
    switch (event->key()) {
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
        case Qt::Key_Shift:
        case Qt::Key_Alt:
        case Qt::Key_Control:
        case Qt::Key_AltGr:
            event->setAccepted(false);
            return;
    }

    double moveStep = 1.0;

    if (event->modifiers().testFlag(Qt::ShiftModifier))
        moveStep = 10.0;

    if (!event->isAutoRepeat()) {
        QList<FormEditorItem*> movableItems(movingItems(items()));
        if (movableItems.isEmpty())
            return;

        m_moveManipulator.setItems(movableItems);
//        m_selectionIndicator.hide();
        m_resizeIndicator.hide();
Marco Bubke's avatar
Marco Bubke committed
185
        m_anchorIndicator.hide();
186
        m_bindingIndicator.hide();
187
        m_moveManipulator.beginRewriterTransaction();
188 189
    }

190
    switch (event->key()) {
191 192 193 194 195 196
        case Qt::Key_Left: m_moveManipulator.moveBy(-moveStep, 0.0); break;
        case Qt::Key_Right: m_moveManipulator.moveBy(moveStep, 0.0); break;
        case Qt::Key_Up: m_moveManipulator.moveBy(0.0, -moveStep); break;
        case Qt::Key_Down: m_moveManipulator.moveBy(0.0, moveStep); break;
    }

197 198 199 200
    if (event->key() == Qt::Key_Escape && !m_movingItems.isEmpty()) {
       event->accept();
       view()->changeToSelectionTool();
    }
201 202 203 204
}

void MoveTool::keyReleaseEvent(QKeyEvent *keyEvent)
{
205
    switch (keyEvent->key()) {
206 207 208 209 210 211 212 213 214 215 216 217
        case Qt::Key_Shift:
        case Qt::Key_Alt:
        case Qt::Key_Control:
        case Qt::Key_AltGr:
            keyEvent->setAccepted(false);
            return;
    }

    if (!keyEvent->isAutoRepeat()) {
        m_moveManipulator.clear();
//        m_selectionIndicator.show();
        m_resizeIndicator.show();
Marco Bubke's avatar
Marco Bubke committed
218
        m_anchorIndicator.show();
219
        m_bindingIndicator.show();
220 221 222
    }
}

223
void  MoveTool::dragLeaveEvent(const QList<QGraphicsItem*> &/*itemList*/, QGraphicsSceneDragDropEvent * /*event*/)
224 225 226 227
{

}

228
void  MoveTool::dragMoveEvent(const QList<QGraphicsItem*> &/*itemList*/, QGraphicsSceneDragDropEvent * /*event*/)
229 230 231 232
{

}

233
void MoveTool::mouseReleaseEvent(const QList<QGraphicsItem*> &itemList,
234 235
                                 QGraphicsSceneMouseEvent *event)
{
236 237 238
    if (m_moveManipulator.isActive()) {
        if (m_movingItems.isEmpty())
            return;
239

240
        m_moveManipulator.end(generateUseSnapping(event->modifiers()));
241

242 243
        m_selectionIndicator.show();
        m_resizeIndicator.show();
Marco Bubke's avatar
Marco Bubke committed
244
        m_anchorIndicator.show();
245
        m_bindingIndicator.show();
246
        m_movingItems.clear();
247
    }
248 249

    AbstractFormEditorTool::mouseReleaseEvent(itemList, event);
Thomas Hartmann's avatar
Thomas Hartmann committed
250 251

    view()->changeToSelectionTool();
252 253
}

254
void MoveTool::mouseDoubleClickEvent(const QList<QGraphicsItem*> &itemList, QGraphicsSceneMouseEvent *event)
255
{
256
    AbstractFormEditorTool::mouseDoubleClickEvent(itemList, event);
257 258 259 260 261 262 263 264 265 266 267 268
}

void MoveTool::itemsAboutToRemoved(const QList<FormEditorItem*> &removedItemList)
{
    foreach (FormEditorItem* removedItem, removedItemList)
        m_movingItems.removeOne(removedItem);
}

void MoveTool::selectedItemsChanged(const QList<FormEditorItem*> &itemList)
{
    m_selectionIndicator.setItems(movingItems(itemList));
    m_resizeIndicator.setItems(itemList);
Marco Bubke's avatar
Marco Bubke committed
269
    m_anchorIndicator.setItems(itemList);
270
    m_bindingIndicator.setItems(itemList);
271 272 273
    updateMoveManipulator();
}

Thomas Hartmann's avatar
Thomas Hartmann committed
274
void MoveTool::instancesCompleted(const QList<FormEditorItem*> & /*itemList*/)
275 276 277
{
}

278 279 280 281 282
void  MoveTool::instancesParentChanged(const QList<FormEditorItem *> &itemList)
{
    m_moveManipulator.synchronizeInstanceParent(itemList);
}

283 284 285 286
void MoveTool::instancePropertyChange(const QList<QPair<ModelNode, PropertyName> > & /*propertyList*/)
{
}

287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347
bool MoveTool::haveSameParent(const QList<FormEditorItem*> &itemList)
{
    if (itemList.isEmpty())
        return false;

    QGraphicsItem *firstParent = itemList.first()->parentItem();
    foreach (FormEditorItem* item, itemList)
    {
        if (firstParent != item->parentItem())
            return false;
    }

    return true;
}

bool MoveTool::isAncestorOfAllItems(FormEditorItem* maybeAncestorItem,
                                    const QList<FormEditorItem*> &itemList)
{
    foreach (FormEditorItem* item, itemList)
    {
        if (!maybeAncestorItem->isAncestorOf(item) && item != maybeAncestorItem)
            return false;
    }

    return true;
}


FormEditorItem* MoveTool::ancestorIfOtherItemsAreChild(const QList<FormEditorItem*> &itemList)
{
    if (itemList.isEmpty())
        return 0;


    foreach (FormEditorItem* item, itemList)
    {
        if (isAncestorOfAllItems(item, itemList))
            return item;
    }

    return 0;
}

void MoveTool::updateMoveManipulator()
{
    if (m_moveManipulator.isActive())
        return;
}

void MoveTool::beginWithPoint(const QPointF &beginPoint)
{
    m_movingItems = movingItems(items());
    if (m_movingItems.isEmpty())
        return;

    m_moveManipulator.setItems(m_movingItems);
    m_moveManipulator.begin(beginPoint);
}



348 349 350 351 352 353 354
QList<FormEditorItem*> movalbeItems(const QList<FormEditorItem*> &itemList)
{
    QList<FormEditorItem*> filteredItemList(itemList);

    QMutableListIterator<FormEditorItem*> listIterator(filteredItemList);
    while (listIterator.hasNext()) {
        FormEditorItem *item = listIterator.next();
355 356 357 358
        if (!item->qmlItemNode().isValid()
                || !item->qmlItemNode().instanceIsMovable()
                || !item->qmlItemNode().modelIsMovable()
                || item->qmlItemNode().instanceIsInLayoutable())
359 360 361 362 363
            listIterator.remove();
    }

    return filteredItemList;
}
364 365 366

QList<FormEditorItem*> MoveTool::movingItems(const QList<FormEditorItem*> &selectedItemList)
{
367 368 369
    QList<FormEditorItem*> filteredItemList = movalbeItems(selectedItemList);

    FormEditorItem* ancestorItem = ancestorIfOtherItemsAreChild(filteredItemList);
370 371 372 373 374 375 376 377 378 379 380 381 382

    if (ancestorItem != 0 && ancestorItem->qmlItemNode().isRootNode()) {
//        view()->changeToSelectionTool();
        return QList<FormEditorItem*>();
    }


    if (ancestorItem != 0 && ancestorItem->parentItem() != 0)  {
        QList<FormEditorItem*> ancestorItemList;
        ancestorItemList.append(ancestorItem);
        return ancestorItemList;
    }

383
    if (!haveSameParent(filteredItemList)) {
384 385 386 387
//        view()->changeToSelectionTool();
        return QList<FormEditorItem*>();
    }

388
    return filteredItemList;
389 390 391 392
}

void MoveTool::formEditorItemsChanged(const QList<FormEditorItem*> &itemList)
{
393 394 395 396 397 398
    const QList<FormEditorItem*> selectedItemList = filterSelectedModelNodes(itemList);

    m_selectionIndicator.updateItems(selectedItemList);
    m_resizeIndicator.updateItems(selectedItemList);
    m_anchorIndicator.updateItems(selectedItemList);
    m_bindingIndicator.updateItems(selectedItemList);
399
    m_contentNotEditableIndicator.updateItems(selectedItemList);
400 401
}

402 403 404 405
void MoveTool::focusLost()
{
}

406
}