/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Designer of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "formwindow.h"
#include "formeditor.h"
#include "formwindow_dnditem.h"
#include "formwindow_widgetstack.h"
#include "formwindowcursor.h"
#include "formwindowmanager.h"
#include "tool_widgeteditor.h"
#include "widgetselection.h"
#include "qtresourcemodel_p.h"
#include "widgetfactory_p.h"

// shared
#include <metadatabase_p.h>
#include <qdesigner_tabwidget_p.h>
#include <qdesigner_toolbox_p.h>
#include <qdesigner_stackedbox_p.h>
#include <qdesigner_resource.h>
#include <qdesigner_command_p.h>
#include <qdesigner_command2_p.h>
#include <qdesigner_propertycommand_p.h>
#include <qdesigner_taskmenu_p.h>
#include <qdesigner_widget_p.h>
#include <qdesigner_utils_p.h>
#include <qlayout_widget_p.h>
#include <spacer_widget_p.h>
#include <invisible_widget_p.h>
#include <layoutinfo_p.h>
#include <qdesigner_objectinspector_p.h>
#include <connectionedit_p.h>
#include <actionprovider_p.h>
#include <ui4_p.h>
#include <deviceprofile_p.h>
#include <shared_settings_p.h>
#include <grid_p.h>

#include <QtDesigner/QExtensionManager>
#include <QtDesigner/QDesignerWidgetDataBaseInterface>
#include <QtDesigner/QDesignerPropertySheetExtension>
#include <QtDesigner/QDesignerWidgetFactoryInterface>
#include <QtDesigner/QDesignerContainerExtension>
#include <QtDesigner/QDesignerTaskMenuExtension>
#include <QtDesigner/QDesignerWidgetBoxInterface>
#include <abstractdialoggui_p.h>

#include <QtCore/QtDebug>
#include <QtCore/QBuffer>
#include <QtCore/QTimer>
#include <QtCore/QXmlStreamReader>
#include <QtGui/QMenu>
#include <QtGui/QAction>
#include <QtGui/QActionGroup>
#include <QtGui/QClipboard>
#include <QtGui/QUndoGroup>
#include <QtGui/QScrollArea>
#include <QtGui/QRubberBand>
#include <QtGui/QApplication>
#include <QtGui/QSplitter>
#include <QtGui/QPainter>
#include <QtGui/QGroupBox>
#include <QtGui/QDockWidget>
#include <QtGui/QToolBox>
#include <QtGui/QStackedWidget>
#include <QtGui/QTabWidget>
#include <QtGui/QButtonGroup>

Q_DECLARE_METATYPE(QWidget*)

QT_BEGIN_NAMESPACE

namespace {
class BlockSelection
{
public:
    BlockSelection(qdesigner_internal::FormWindow *fw)
        : m_formWindow(fw),
          m_blocked(m_formWindow->blockSelectionChanged(true))
    {
    }

    ~BlockSelection()
    {
        if (m_formWindow)
            m_formWindow->blockSelectionChanged(m_blocked);
    }

private:
    QPointer<qdesigner_internal::FormWindow> m_formWindow;
    const bool m_blocked;
};

enum { debugFormWindow = 0 };
}

namespace qdesigner_internal {

// ------------------------ FormWindow::Selection
// Maintains a pool of WidgetSelections to be used for selected widgets.

class FormWindow::Selection
{
public:
    Selection();
    ~Selection();

    // Clear
    void clear();

    // Also clear out the pool. Call if reparenting of the main container occurs.
    void  clearSelectionPool();

    void repaintSelection(QWidget *w);
    void repaintSelection();

    bool isWidgetSelected(QWidget *w) const;
    QWidgetList selectedWidgets() const;

    WidgetSelection *addWidget(FormWindow* fw, QWidget *w);
    // remove widget, return new current widget or 0
    QWidget* removeWidget(QWidget *w);

    void raiseList(const QWidgetList& l);
    void raiseWidget(QWidget *w);

    void updateGeometry(QWidget *w);

    void hide(QWidget *w);
    void show(QWidget *w);

private:

    typedef QList<WidgetSelection *> SelectionPool;
    SelectionPool m_selectionPool;

    typedef QHash<QWidget *, WidgetSelection *> SelectionHash;
    SelectionHash m_usedSelections;
};

FormWindow::Selection::Selection()
{
}

FormWindow::Selection::~Selection()
{
    clearSelectionPool();
}

void FormWindow::Selection::clear()
{
    if (!m_usedSelections.empty()) {
        const SelectionHash::iterator mend = m_usedSelections.end();
        for (SelectionHash::iterator it = m_usedSelections.begin(); it != mend; ++it) {
            it.value()->setWidget(0);
        }
        m_usedSelections.clear();
    }
}

void  FormWindow::Selection::clearSelectionPool()
{
    clear();
    qDeleteAll(m_selectionPool);
    m_selectionPool.clear();
}

WidgetSelection *FormWindow::Selection::addWidget(FormWindow* fw, QWidget *w)
{
    WidgetSelection *rc = m_usedSelections.value(w);
    if (rc != 0) {
        rc->show();
        rc->updateActive();
        return rc;
    }
    // find a free one in the pool
    const SelectionPool::iterator pend = m_selectionPool.end();
    for (SelectionPool::iterator it = m_selectionPool.begin(); it != pend; ++it) {
        if (! (*it)->isUsed()) {
            rc = *it;
            break;
        }
    }

    if (rc == 0) {
        rc = new WidgetSelection(fw);
        m_selectionPool.push_back(rc);
    }

    m_usedSelections.insert(w, rc);
    rc->setWidget(w);
    return rc;
}

QWidget* FormWindow::Selection::removeWidget(QWidget *w)
{
    WidgetSelection *s = m_usedSelections.value(w);
    if (!s)
        return w;

    s->setWidget(0);
    m_usedSelections.remove(w);

    if (m_usedSelections.isEmpty())
        return 0;

    return (*m_usedSelections.begin())->widget();
}

void FormWindow::Selection::repaintSelection(QWidget *w)
{
    if (WidgetSelection *s = m_usedSelections.value(w))
        s->update();
}

void FormWindow::Selection::repaintSelection()
{
    const SelectionHash::iterator mend = m_usedSelections.end();
    for (SelectionHash::iterator it = m_usedSelections.begin(); it != mend; ++it) {
        it.value()->update();
    }
}

bool FormWindow::Selection::isWidgetSelected(QWidget *w) const{
    return  m_usedSelections.contains(w);
}

QWidgetList FormWindow::Selection::selectedWidgets() const
{
    return m_usedSelections.keys();
}

void FormWindow::Selection::raiseList(const QWidgetList& l)
{
    const SelectionHash::iterator mend = m_usedSelections.end();
    for (SelectionHash::iterator it = m_usedSelections.begin(); it != mend; ++it) {
        WidgetSelection *w = it.value();
        if (l.contains(w->widget()))
            w->show();
    }
}

void FormWindow::Selection::raiseWidget(QWidget *w)
{
    if (WidgetSelection *s = m_usedSelections.value(w))
        s->show();
}

void FormWindow::Selection::updateGeometry(QWidget *w)
{
    if (WidgetSelection *s = m_usedSelections.value(w)) {
        s->updateGeometry();
    }
}

void FormWindow::Selection::hide(QWidget *w)
{
    if (WidgetSelection *s = m_usedSelections.value(w))
        s->hide();
}

void FormWindow::Selection::show(QWidget *w)
{
    if (WidgetSelection *s = m_usedSelections.value(w))
        s->show();
}

// ------------------------ FormWindow
FormWindow::FormWindow(FormEditor *core, QWidget *parent, Qt::WindowFlags flags) :
    FormWindowBase(core, parent, flags),
    m_mouseState(NoMouseState),
    m_core(core),
    m_selection(new Selection),
    m_widgetStack(new FormWindowWidgetStack(this)),
    m_contextMenuPosition(-1, -1)
{
    // Apply settings to formcontainer
    deviceProfile().apply(core, m_widgetStack->formContainer(), qdesigner_internal::DeviceProfile::ApplyFormParent);

    setLayout(m_widgetStack->layout());
    init();

    m_cursor = new FormWindowCursor(this, this);

    core->formWindowManager()->addFormWindow(this);

    setDirty(false);
    setAcceptDrops(true);
}

FormWindow::~FormWindow()
{
    Q_ASSERT(core() != 0);
    Q_ASSERT(core()->metaDataBase() != 0);
    Q_ASSERT(core()->formWindowManager() != 0);

    core()->formWindowManager()->removeFormWindow(this);
    core()->metaDataBase()->remove(this);

    QWidgetList l = widgets();
    foreach (QWidget *w, l)
        core()->metaDataBase()->remove(w);

    m_widgetStack = 0;
    m_rubberBand = 0;
    if (resourceSet())
        core()->resourceModel()->removeResourceSet(resourceSet());
    delete m_selection;
}

QDesignerFormEditorInterface *FormWindow::core() const
{
    return m_core;
}

QDesignerFormWindowCursorInterface *FormWindow::cursor() const
{
    return m_cursor;
}

void FormWindow::updateWidgets()
{
    if (!m_mainContainer)
        return;
}

int FormWindow::widgetDepth(const QWidget *w)
{
    int d = -1;
    while (w && !w->isWindow()) {
        d++;
        w = w->parentWidget();
    }

    return d;
}

bool FormWindow::isChildOf(const QWidget *c, const QWidget *p)
{
    while (c) {
        if (c == p)
            return true;
        c = c->parentWidget();
    }
    return false;
}

void FormWindow::setCursorToAll(const QCursor &c, QWidget *start)
{
#ifndef QT_NO_CURSOR
    start->setCursor(c);
    const QWidgetList widgets = qFindChildren<QWidget*>(start);
    foreach (QWidget *widget, widgets) {
        if (!qobject_cast<WidgetHandle*>(widget)) {
            widget->setCursor(c);
        }
    }
#endif
}

void FormWindow::init()
{
    if (FormWindowManager *manager = qobject_cast<FormWindowManager*> (core()->formWindowManager())) {
        manager->undoGroup()->addStack(m_undoStack.qundoStack());
    }

    m_blockSelectionChanged = false;

    m_defaultMargin = INT_MIN;
    m_defaultSpacing = INT_MIN;

    connect(m_widgetStack, SIGNAL(currentToolChanged(int)), this, SIGNAL(toolChanged(int)));

    m_selectionChangedTimer = new QTimer(this);
    m_selectionChangedTimer->setSingleShot(true);
    connect(m_selectionChangedTimer, SIGNAL(timeout()), this, SLOT(selectionChangedTimerDone()));

    m_checkSelectionTimer = new QTimer(this);
    m_checkSelectionTimer->setSingleShot(true);
    connect(m_checkSelectionTimer, SIGNAL(timeout()), this, SLOT(checkSelectionNow()));

    m_geometryChangedTimer = new QTimer(this);
    m_geometryChangedTimer->setSingleShot(true);
    connect(m_geometryChangedTimer, SIGNAL(timeout()), this, SIGNAL(geometryChanged()));

    m_rubberBand = 0;

    setFocusPolicy(Qt::StrongFocus);

    m_mainContainer = 0;
    m_currentWidget = 0;

    connect(&m_undoStack, SIGNAL(changed()), this, SIGNAL(changed()));
    connect(&m_undoStack, SIGNAL(changed()), this, SLOT(checkSelection()));

    core()->metaDataBase()->add(this);

    initializeCoreTools();

    QAction *a = new QAction(this);
    a->setText(tr("Edit contents"));
    a->setShortcut(tr("F2"));
    connect(a, SIGNAL(triggered()), this, SLOT(editContents()));
    addAction(a);
}

QWidget *FormWindow::mainContainer() const
{
    return m_mainContainer;
}


void FormWindow::clearMainContainer()
{
    if (m_mainContainer) {
        setCurrentTool(0);
        m_widgetStack->setMainContainer(0);
        core()->metaDataBase()->remove(m_mainContainer);
        unmanageWidget(m_mainContainer);
        delete m_mainContainer;
        m_mainContainer = 0;
    }
}

void FormWindow::setMainContainer(QWidget *w)
{
    if (w == m_mainContainer) {
        // nothing to do
        return;
    }

    clearMainContainer();

    m_mainContainer = w;
    const QSize sz = m_mainContainer->size();

    m_widgetStack->setMainContainer(m_mainContainer);
    m_widgetStack->setCurrentTool(m_widgetEditor);

    setCurrentWidget(m_mainContainer);
    manageWidget(m_mainContainer);

    if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), m_mainContainer)) {
        sheet->setVisible(sheet->indexOf(QLatin1String("windowTitle")), true);
        sheet->setVisible(sheet->indexOf(QLatin1String("windowIcon")), true);
        sheet->setVisible(sheet->indexOf(QLatin1String("windowModality")), true);
        sheet->setVisible(sheet->indexOf(QLatin1String("windowOpacity")), true);
        sheet->setVisible(sheet->indexOf(QLatin1String("windowFilePath")), true);
        // ### generalize
    }

    m_mainContainer->setFocusPolicy(Qt::StrongFocus);
    m_mainContainer->resize(sz);

    emit mainContainerChanged(m_mainContainer);
}

QWidget *FormWindow::findTargetContainer(QWidget *widget) const
{
    Q_ASSERT(widget);

    while (QWidget *parentWidget = widget->parentWidget()) {
        if (LayoutInfo::layoutType(m_core, parentWidget) == LayoutInfo::NoLayout && isManaged(widget))
            return widget;

        widget = parentWidget;
    }

    return mainContainer();
}

static inline void clearObjectInspectorSelection(const QDesignerFormEditorInterface *core)
{
    if (QDesignerObjectInspector *oi = qobject_cast<QDesignerObjectInspector *>(core->objectInspector()))
        oi->clearSelection();
}

// Find a parent of a desired selection state
static QWidget *findSelectedParent(QDesignerFormWindowInterface *fw, const QWidget *w, bool selected)
{
    const QDesignerFormWindowCursorInterface *cursor = fw->cursor();
    QWidget *mainContainer = fw->mainContainer();
    for (QWidget *p = w->parentWidget(); p && p != mainContainer; p = p->parentWidget())
        if (fw->isManaged(p))
            if (cursor->isWidgetSelected(p) == selected)
                return p;
    return 0;
}

// Mouse modifiers.

enum MouseFlags { ToggleSelectionModifier = 0x1, CycleParentModifier=0x2, CopyDragModifier=0x4 };

static inline unsigned mouseFlags(Qt::KeyboardModifiers mod)
{
    switch (mod) {
    case Qt::ShiftModifier:
        return CycleParentModifier;
        break;
#ifdef Q_WS_MAC
    case Qt::AltModifier: // "Alt" or "option" key on Mac means copy
        return CopyDragModifier;
#endif
    case Qt::ControlModifier:
        return CopyDragModifier|ToggleSelectionModifier;
        break;
    default:
        break;
    }
    return 0;
}

// Handle the click selection: Do toggling/cycling
// of parents according to the modifiers.
void FormWindow::handleClickSelection(QWidget *managedWidget, unsigned mouseMode)
{
    const bool sameWidget = managedWidget == m_lastClickedWidget;
    m_lastClickedWidget = managedWidget;

    const bool selected = isWidgetSelected(managedWidget);
    if (debugFormWindow)
        qDebug() << "handleClickSelection" << managedWidget << " same=" << sameWidget << " mouse= " << mouseMode << " selected=" << selected;

    // // toggle selection state of widget
    if (mouseMode & ToggleSelectionModifier) {
        selectWidget(managedWidget, !selected);
        return;
    }

    QWidget *selectionCandidate = 0;
    // Hierarchy cycling: If the same widget clicked again: Attempt to cycle
    // trough the hierarchy. Find the next currently selected parent
    if (sameWidget && (mouseMode & CycleParentModifier))
        if (QWidget *currentlySelectedParent = selected ? managedWidget : findSelectedParent(this, managedWidget, true))
            selectionCandidate = findSelectedParent(this, currentlySelectedParent, false);
    // Not the same widget, list wrapped over or there was no unselected parent
    if (!selectionCandidate && !selected)
        selectionCandidate = managedWidget;

    if (selectionCandidate)
        selectSingleWidget(selectionCandidate);
}

void FormWindow::selectSingleWidget(QWidget *w)
{
    clearSelection(false);
    selectWidget(w, true);
    raiseChildSelections(w);
}

bool FormWindow::handleMousePressEvent(QWidget * widget, QWidget *managedWidget, QMouseEvent *e)
{
    m_mouseState = NoMouseState;
    m_startPos = QPoint();
    e->accept();

    BlockSelection blocker(this);

    if (core()->formWindowManager()->activeFormWindow() != this)
        core()->formWindowManager()->setActiveFormWindow(this);

    const Qt::MouseButtons buttons = e->buttons();
    if (buttons != Qt::LeftButton && buttons != Qt::MidButton)
        return true;

    m_startPos = mapFromGlobal(e->globalPos());

    if (debugFormWindow)
        qDebug() << "handleMousePressEvent:" <<  widget << ',' << managedWidget;

    if (buttons == Qt::MidButton || isMainContainer(managedWidget) == true) { // press was on the formwindow
        clearObjectInspectorSelection(m_core);  // We might have a toolbar or non-widget selected in the object inspector.
        clearSelection(false);

        m_mouseState = MouseDrawRubber;
        m_currRect = QRect();
        startRectDraw(mapFromGlobal(e->globalPos()), this, Rubber);
        return true;
    }
    if (buttons != Qt::LeftButton)
        return true;

    const unsigned mouseMode = mouseFlags(e->modifiers());

    /* Normally, we want to be able to click /select-on-press to drag away
     * the widget in the next step. However, in the case of a widget which
     * itself or whose parent is selected, we defer the selection to the
     * release event.
     * This is to prevent children from being dragged away from layouts
     * when their layouts are selected and one wants to move the layout.
     * Note that toggle selection is only deferred if the widget is already
     * selected, so, it is still possible to just Ctrl+Click and CopyDrag. */
    const bool deferSelection = isWidgetSelected(managedWidget) || findSelectedParent(this, managedWidget, true);
    if (deferSelection) {
        m_mouseState = MouseDeferredSelection;
    } else {
        // Cycle the parent unless we explicitly want toggle
        const unsigned effectiveMouseMode = (mouseMode & ToggleSelectionModifier) ? mouseMode : static_cast<unsigned>(CycleParentModifier);
        handleClickSelection(managedWidget, effectiveMouseMode);
    }
    return true;
}

// We can drag widget in managed layouts except splitter.
static bool canDragWidgetInLayout(const QDesignerFormEditorInterface *core, QWidget *w)
{
    bool managed;
    const LayoutInfo::Type type = LayoutInfo::laidoutWidgetType(core ,w, &managed);
    if (!managed)
        return false;
    switch (type) {
    case LayoutInfo::NoLayout:
    case LayoutInfo::HSplitter:
    case LayoutInfo::VSplitter:
       return false;
    default:
       break;
    }
    return true;
}

bool FormWindow::handleMouseMoveEvent(QWidget *, QWidget *, QMouseEvent *e)
{
    e->accept();
    if (m_startPos.isNull())
        return true;

    const QPoint pos = mapFromGlobal(e->globalPos());

    switch (m_mouseState) {
    case MouseDrawRubber:  // Rubber band with left/middle mouse
        continueRectDraw(pos, this, Rubber);
        return true;
    case MouseMoveDrag: // Spurious move event after drag started?
        return true;
    default:
        break;
    }

    if (e->buttons() != Qt::LeftButton)
        return true;

    const bool canStartDrag = (m_startPos - pos).manhattanLength() > QApplication::startDragDistance();

    if (canStartDrag == false) {
        // nothing to do
        return true;
    }

    m_mouseState = MouseMoveDrag;
    const bool blocked = blockSelectionChanged(true);

    QWidgetList sel = selectedWidgets();
    simplifySelection(&sel);

    QSet<QWidget*> widget_set;

    foreach (QWidget *child, sel) { // Move parent layout or container?
        QWidget *current = child;

        bool done = false;
        while (!isMainContainer(current) && !done) {
            if (!isManaged(current)) {
                current = current->parentWidget();
                continue;
            } else if (LayoutInfo::isWidgetLaidout(core(), current)) {
                // Go up to parent of layout if shift pressed, else do that only for splitters
                if (!canDragWidgetInLayout(core(), current)) {
                    current = current->parentWidget();
                    continue;
                }
            }
            done = true;
        }

        if (current == mainContainer())
            continue;

        widget_set.insert(current);
    }

    sel = widget_set.toList();
    QDesignerFormWindowCursorInterface *c = cursor();
    QWidget *current = c->current();
    if (sel.contains(current)) {
        sel.removeAll(current);
        sel.prepend(current);
    }

    QList<QDesignerDnDItemInterface*> item_list;
    const QPoint globalPos = mapToGlobal(m_startPos);
    const QDesignerDnDItemInterface::DropType dropType = (mouseFlags(e->modifiers()) & CopyDragModifier) ?
                            QDesignerDnDItemInterface::CopyDrop : QDesignerDnDItemInterface::MoveDrop;
    foreach (QWidget *widget, sel) {
        item_list.append(new FormWindowDnDItem(dropType,  this, widget, globalPos));
        if (dropType == QDesignerDnDItemInterface::MoveDrop) {
            m_selection->hide(widget);
            widget->hide();
        }
    }

    blockSelectionChanged(blocked);

    if (!sel.empty()) // reshow selection?
        if (QDesignerMimeData::execDrag(item_list, core()->topLevel()) == Qt::IgnoreAction && dropType == QDesignerDnDItemInterface::MoveDrop)
            foreach (QWidget *widget, sel)
                m_selection->show(widget);

    m_startPos = QPoint();

    return true;
}

bool FormWindow::handleMouseReleaseEvent(QWidget *w, QWidget *mw, QMouseEvent *e)
{
    const MouseState oldState = m_mouseState;
    m_mouseState = NoMouseState;

    if (debugFormWindow)
        qDebug() << "handleMouseeleaseEvent:" << w << ',' << mw << "state=" << oldState;

    if (oldState == MouseDoubleClicked)
        return true;

    e->accept();

    switch (oldState) {
    case MouseDrawRubber: {  // we were drawing a rubber selection
        endRectDraw(); // get rid of the rectangle
        const bool blocked = blockSelectionChanged(true);
        selectWidgets(); // select widgets which intersect the rect
        blockSelectionChanged(blocked);
    }
        break;
    // Deferred select: Select the child here unless the parent was moved.
    case MouseDeferredSelection:
        handleClickSelection(mw, mouseFlags(e->modifiers()));
        break;
    default:
        break;
    }

    m_startPos = QPoint();

    /* Inform about selection changes (left/mid or context menu). Also triggers
     * in the case of an empty rubber drag that cleared the selection in
     * MousePressEvent. */
    switch (e->button()) {
    case Qt::LeftButton:
    case Qt::MidButton:
    case Qt::RightButton:
        emitSelectionChanged();
        break;
    default:
        break;
    }

    return true;
}

void FormWindow::checkPreviewGeometry(QRect &r)
{
    if (!rect().contains(r)) {
        if (r.left() < rect().left())
            r.moveTopLeft(QPoint(0, r.top()));
        if (r.right() > rect().right())
            r.moveBottomRight(QPoint(rect().right(), r.bottom()));
        if (r.top() < rect().top())
            r.moveTopLeft(QPoint(r.left(), rect().top()));
        if (r.bottom() > rect().bottom())
            r.moveBottomRight(QPoint(r.right(), rect().bottom()));
    }
}

void FormWindow::startRectDraw(const QPoint &pos, QWidget *, RectType t)
{
    m_rectAnchor = (t == Insert) ? designerGrid().snapPoint(pos) : pos;

    m_currRect = QRect(m_rectAnchor, QSize(0, 0));
    if (!m_rubberBand)
        m_rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
    m_rubberBand->setGeometry(m_currRect);
    m_rubberBand->show();
}

void FormWindow::continueRectDraw(const QPoint &pos, QWidget *, RectType t)
{
    const QPoint p2 = (t == Insert) ? designerGrid().snapPoint(pos) : pos;

    QRect r(m_rectAnchor, p2);
    r = r.normalized();

    if (m_currRect == r)
        return;

    if (r.width() > 1 || r.height() > 1) {
        m_currRect = r;
        if (m_rubberBand)
            m_rubberBand->setGeometry(m_currRect);
    }
}

void FormWindow::endRectDraw()
{
    if (m_rubberBand) {
        delete m_rubberBand;
        m_rubberBand = 0;
    }
}

QWidget *FormWindow::currentWidget() const
{
    return m_currentWidget;
}

bool FormWindow::setCurrentWidget(QWidget *currentWidget)
{
     if (debugFormWindow)
        qDebug() << "setCurrentWidget:" <<  m_currentWidget << " --> " << currentWidget;
     if (currentWidget == m_currentWidget)
         return false;
     // repaint the old widget unless it is the main window
     if (m_currentWidget && m_currentWidget != mainContainer()) {
         m_selection->repaintSelection(m_currentWidget);
     }
     // set new and repaint
     m_currentWidget = currentWidget;
     if (m_currentWidget && m_currentWidget != mainContainer()) {
         m_selection->repaintSelection(m_currentWidget);
     }
     return true;
}

void FormWindow::selectWidget(QWidget* w, bool select)
{
    if (trySelectWidget(w, select))
        emitSelectionChanged();
}

// Selects a widget and determines the new current one. Returns true if a change occurs.
bool FormWindow::trySelectWidget(QWidget *w, bool select)
{
    if (debugFormWindow)
        qDebug() << "trySelectWidget:" << w << select;
    if (!isManaged(w) && !isCentralWidget(w))
        return false;

    if (!select && !isWidgetSelected(w))
        return false;

    if (!mainContainer())
        return false;

    if (isMainContainer(w) || isCentralWidget(w)) {
        setCurrentWidget(mainContainer());
        return true;
    }

    if (select) {
        setCurrentWidget(w);
        m_selection->addWidget(this, w);
    } else {
        QWidget *newCurrent = m_selection->removeWidget(w);
        if (!newCurrent)
            newCurrent = mainContainer();
        setCurrentWidget(newCurrent);
    }
    return true;
}

void FormWindow::clearSelection(bool changePropertyDisplay)
{
    if (debugFormWindow)
        qDebug() << "clearSelection(" <<  changePropertyDisplay << ')';
    // At all events, we need a current widget.
    m_selection->clear();
    setCurrentWidget(mainContainer());

    if (changePropertyDisplay)
        emitSelectionChanged();
}

void FormWindow::emitSelectionChanged()
{
    if (m_blockSelectionChanged == true) {
        // nothing to do
        return;
    }

    m_selectionChangedTimer->start(0);
}

void FormWindow::selectionChangedTimerDone()
{
    emit selectionChanged();
}

bool FormWindow::isWidgetSelected(QWidget *w) const
{
    return m_selection->isWidgetSelected(w);
}

bool FormWindow::isMainContainer(const QWidget *w) const
{
    return w && (w == this || w == mainContainer());
}

void FormWindow::updateChildSelections(QWidget *w)
{
    const QWidgetList l = qFindChildren<QWidget*>(w);
    if (!l.empty()) {
        const QWidgetList::const_iterator lcend = l.constEnd();
        for (QWidgetList::const_iterator it = l.constBegin(); it != lcend; ++it) {
            QWidget *w = *it;
            if (isManaged(w))
                updateSelection(w);
        }
    }
}

void FormWindow::repaintSelection()
{
    m_selection->repaintSelection();
}

void FormWindow::raiseSelection(QWidget *w)
{
    m_selection->raiseWidget(w);
}

void FormWindow::updateSelection(QWidget *w)
{
    if (!w->isVisibleTo(this)) {
        selectWidget(w, false);
    } else {
        m_selection->updateGeometry(w);
    }
}

QWidget *FormWindow::designerWidget(QWidget *w) const
{
    while ((w && !isMainContainer(w) && !isManaged(w)) || isCentralWidget(w))
        w = w->parentWidget();

    return w;
}

bool FormWindow::isCentralWidget(QWidget *w) const
{
    if (QMainWindow *mainWindow = qobject_cast<QMainWindow*>(mainContainer()))
        return w == mainWindow->centralWidget();

    return false;
}

void FormWindow::ensureUniqueObjectName(QObject *object)
{
    QString name = object->objectName();
    if (name.isEmpty()) {
        QDesignerWidgetDataBaseInterface *db = core()->widgetDataBase();
        if (QDesignerWidgetDataBaseItemInterface *item = db->item(db->indexOfObject(object)))
            name = qdesigner_internal::qtify(item->name());
    }
    unify(object, name, true);
    object->setObjectName(name);
}

template <class Iterator>
static inline void insertNames(const QDesignerMetaDataBaseInterface *metaDataBase,
                               Iterator it, const Iterator &end,
                               QObject *excludedObject, QSet<QString> &nameSet)
{
    for ( ; it != end; ++it)
        if (excludedObject != *it && metaDataBase->item(*it))
            nameSet.insert((*it)->objectName());
}

static QSet<QString> languageKeywords()
{
    static QSet<QString> keywords;
    if (keywords.isEmpty()) {
        // C++ keywords
        keywords.insert(QLatin1String("asm"));
        keywords.insert(QLatin1String("auto"));
        keywords.insert(QLatin1String("bool"));
        keywords.insert(QLatin1String("break"));
        keywords.insert(QLatin1String("case"));
        keywords.insert(QLatin1String("catch"));
        keywords.insert(QLatin1String("char"));
        keywords.insert(QLatin1String("class"));
        keywords.insert(QLatin1String("const"));
        keywords.insert(QLatin1String("const_cast"));
        keywords.insert(QLatin1String("continue"));
        keywords.insert(QLatin1String("default"));
        keywords.insert(QLatin1String("delete"));
        keywords.insert(QLatin1String("do"));
        keywords.insert(QLatin1String("double"));
        keywords.insert(QLatin1String("dynamic_cast"));
        keywords.insert(QLatin1String("else"));
        keywords.insert(QLatin1String("enum"));
        keywords.insert(QLatin1String("explicit"));
        keywords.insert(QLatin1String("export"));
        keywords.insert(QLatin1String("extern"));
        keywords.insert(QLatin1String("false"));
        keywords.insert(QLatin1String("float"));
        keywords.insert(QLatin1String("for"));
        keywords.insert(QLatin1String("friend"));
        keywords.insert(QLatin1String("goto"));
        keywords.insert(QLatin1String("if"));
        keywords.insert(QLatin1String("inline"));
        keywords.insert(QLatin1String("int"));
        keywords.insert(QLatin1String("long"));
        keywords.insert(QLatin1String("mutable"));
        keywords.insert(QLatin1String("namespace"));
        keywords.insert(QLatin1String("new"));
        keywords.insert(QLatin1String("NULL"));
        keywords.insert(QLatin1String("operator"));
        keywords.insert(QLatin1String("private"));
        keywords.insert(QLatin1String("protected"));
        keywords.insert(QLatin1String("public"));
        keywords.insert(QLatin1String("register"));
        keywords.insert(QLatin1String("reinterpret_cast"));
        keywords.insert(QLatin1String("return"));
        keywords.insert(QLatin1String("short"));
        keywords.insert(QLatin1String("signed"));
        keywords.insert(QLatin1String("sizeof"));
        keywords.insert(QLatin1String("static"));
        keywords.insert(QLatin1String("static_cast"));
        keywords.insert(QLatin1String("struct"));
        keywords.insert(QLatin1String("switch"));
        keywords.insert(QLatin1String("template"));
        keywords.insert(QLatin1String("this"));
        keywords.insert(QLatin1String("throw"));
        keywords.insert(QLatin1String("true"));
        keywords.insert(QLatin1String("try"));
        keywords.insert(QLatin1String("typedef"));
        keywords.insert(QLatin1String("typeid"));
        keywords.insert(QLatin1String("typename"));
        keywords.insert(QLatin1String("union"));
        keywords.insert(QLatin1String("unsigned"));
        keywords.insert(QLatin1String("using"));
        keywords.insert(QLatin1String("virtual"));
        keywords.insert(QLatin1String("void"));
        keywords.insert(QLatin1String("volatile"));
        keywords.insert(QLatin1String("wchar_t"));
        keywords.insert(QLatin1String("while"));

        // java keywords
        keywords.insert(QLatin1String("abstract"));
        keywords.insert(QLatin1String("assert"));
        keywords.insert(QLatin1String("boolean"));
        keywords.insert(QLatin1String("break"));
        keywords.insert(QLatin1String("byte"));
        keywords.insert(QLatin1String("case"));
        keywords.insert(QLatin1String("catch"));
        keywords.insert(QLatin1String("char"));
        keywords.insert(QLatin1String("class"));
        keywords.insert(QLatin1String("const"));
        keywords.insert(QLatin1String("continue"));
        keywords.insert(QLatin1String("default"));
        keywords.insert(QLatin1String("do"));
        keywords.insert(QLatin1String("double"));
        keywords.insert(QLatin1String("else"));
        keywords.insert(QLatin1String("enum"));
        keywords.insert(QLatin1String("extends"));
        keywords.insert(QLatin1String("false"));
        keywords.insert(QLatin1String("final"));
        keywords.insert(QLatin1String("finality"));
        keywords.insert(QLatin1String("float"));
        keywords.insert(QLatin1String("for"));
        keywords.insert(QLatin1String("goto"));
        keywords.insert(QLatin1String("if"));
        keywords.insert(QLatin1String("implements"));
        keywords.insert(QLatin1String("import"));
        keywords.insert(QLatin1String("instanceof"));
        keywords.insert(QLatin1String("int"));
        keywords.insert(QLatin1String("interface"));
        keywords.insert(QLatin1String("long"));
        keywords.insert(QLatin1String("native"));
        keywords.insert(QLatin1String("new"));
        keywords.insert(QLatin1String("null"));
        keywords.insert(QLatin1String("package"));
        keywords.insert(QLatin1String("private"));
        keywords.insert(QLatin1String("protected"));
        keywords.insert(QLatin1String("public"));
        keywords.insert(QLatin1String("return"));
        keywords.insert(QLatin1String("short"));
        keywords.insert(QLatin1String("static"));
        keywords.insert(QLatin1String("strictfp"));
        keywords.insert(QLatin1String("super"));
        keywords.insert(QLatin1String("switch"));
        keywords.insert(QLatin1String("synchronized"));
        keywords.insert(QLatin1String("this"));
        keywords.insert(QLatin1String("throw"));
        keywords.insert(QLatin1String("throws"));
        keywords.insert(QLatin1String("transient"));
        keywords.insert(QLatin1String("true"));
        keywords.insert(QLatin1String("try"));
        keywords.insert(QLatin1String("void"));
        keywords.insert(QLatin1String("volatile"));
        keywords.insert(QLatin1String("while"));
    }
    return keywords;
}

bool FormWindow::unify(QObject *w, QString &s, bool changeIt)
{
    typedef QSet<QString> StringSet;

    QWidget *main = mainContainer();
    if (!main)
        return true;

    StringSet existingNames = languageKeywords();
    // build a set of existing names of other widget excluding self
    if (!(w->isWidgetType() && isMainContainer(qobject_cast<QWidget*>(w))))
        existingNames.insert(main->objectName());

    const QDesignerMetaDataBaseInterface *metaDataBase = core()->metaDataBase();
    const QWidgetList widgetChildren = qFindChildren<QWidget*>(main);
    if (!widgetChildren.empty())
        insertNames(metaDataBase, widgetChildren.constBegin(), widgetChildren.constEnd(), w, existingNames);

    const QList<QLayout *> layoutChildren = qFindChildren<QLayout*>(main);
    if (!layoutChildren.empty())
        insertNames(metaDataBase, layoutChildren.constBegin(), layoutChildren.constEnd(), w, existingNames);

    const QList<QAction *> actionChildren = qFindChildren<QAction*>(main);
    if (!actionChildren.empty())
        insertNames(metaDataBase, actionChildren.constBegin(), actionChildren.constEnd(), w, existingNames);

    const QList<QButtonGroup *> buttonGroupChildren = qFindChildren<QButtonGroup*>(main);
    if (!buttonGroupChildren.empty())
        insertNames(metaDataBase, buttonGroupChildren.constBegin(), buttonGroupChildren.constEnd(), w, existingNames);

    const StringSet::const_iterator enEnd = existingNames.constEnd();
    if (existingNames.constFind(s) == enEnd)
        return true;
    else
        if (!changeIt)
            return false;

    // split 'name_number'
    qlonglong num = 0;
    qlonglong factor = 1;
    int idx = s.length()-1;
    const ushort zeroUnicode = QLatin1Char('0').unicode();
    for ( ; idx > 0 && s.at(idx).isDigit(); --idx) {
        num += (s.at(idx).unicode() - zeroUnicode) * factor;
        factor *= 10;
    }
    // Position index past '_'.
    const QChar underscore = QLatin1Char('_');
    if (idx >= 0 && s.at(idx) == underscore) {
        idx++;
    }  else {
        num = 1;
        s += underscore;
        idx = s.length();
    }
    // try 'name_n', 'name_n+1'
    for (num++ ; ;num++) {
        s.truncate(idx);
        s += QString::number(num);
        if (existingNames.constFind(s) == enEnd)
            break;
    }
    return false;
}
/* already_in_form is true when we are moving a widget from one parent to another inside the same
 * form. All this means is that InsertWidgetCommand::undo() must not unmanage it. */

void FormWindow::insertWidget(QWidget *w, const QRect &rect, QWidget *container, bool already_in_form)
{
    clearSelection(false);

    beginCommand(tr("Insert widget '%1'").arg(WidgetFactory::classNameOf(m_core, w))); // ### use the WidgetDatabaseItem

    /* Reparenting into a QSplitter automatically adjusts child's geometry. We create the geometry
     * command before we push the reparent command, so that the geometry command has the original
     * geometry of the widget. */
    QRect r = rect;
    Q_ASSERT(r.isValid());
    SetPropertyCommand *geom_cmd = new SetPropertyCommand(this);
    geom_cmd->init(w, QLatin1String("geometry"), r); // ### use rc.size()

    if (w->parentWidget() != container) {
        ReparentWidgetCommand *cmd = new ReparentWidgetCommand(this);
        cmd->init(w, container);
        m_undoStack.push(cmd);
    }

    m_undoStack.push(geom_cmd);

    InsertWidgetCommand *cmd = new InsertWidgetCommand(this);
    cmd->init(w, already_in_form);
    m_undoStack.push(cmd);

    endCommand();

    w->show();
}

QWidget *FormWindow::createWidget(DomUI *ui, const QRect &rc, QWidget *target)
{
    QWidget *container = findContainer(target, false);
    if (!container)
        return 0;
    if (isMainContainer(container)) {
        if (QMainWindow *mw = qobject_cast<QMainWindow*>(container)) {
            Q_ASSERT(mw->centralWidget() != 0);
            container = mw->centralWidget();
        }
    }
    QDesignerResource resource(this);
    const FormBuilderClipboard clipboard = resource.paste(ui, container);
    if (clipboard.m_widgets.size() != 1) // multiple-paste from DomUI not supported yet
        return 0;
    QWidget *widget = clipboard.m_widgets.first();
    insertWidget(widget, rc, container);
    return widget;
}

#ifndef QT_NO_DEBUG
static bool isDescendant(const QWidget *parent, const QWidget *child)
{
    for (; child != 0; child = child->parentWidget()) {
        if (child == parent)
            return true;
    }
    return false;
}
#endif

void FormWindow::resizeWidget(QWidget *widget, const QRect &geometry)
{
    Q_ASSERT(isDescendant(this, widget));

    QRect r = geometry;
    SetPropertyCommand *cmd = new SetPropertyCommand(this);
    cmd->init(widget, QLatin1String("geometry"), r);
    cmd->setText(tr("Resize"));
    m_undoStack.push(cmd);
}

void FormWindow::raiseChildSelections(QWidget *w)
{
    const QWidgetList l = qFindChildren<QWidget*>(w);
    if (l.isEmpty())
        return;
    m_selection->raiseList(l);
}

QWidget *FormWindow::containerAt(const QPoint &pos, QWidget *notParentOf)
{
    QWidget *container = 0;
    int depth = -1;
    const QWidgetList selected = selectedWidgets();
    if (rect().contains(mapFromGlobal(pos))) {
        container = mainContainer();
        depth = widgetDepth(container);
    }

    QListIterator<QWidget*> it(m_widgets);
    while (it.hasNext()) {
        QWidget *wit = it.next();
        if (qobject_cast<QLayoutWidget*>(wit) || qobject_cast<QSplitter*>(wit))
            continue;
        if (!wit->isVisibleTo(this))
            continue;
        if (selected.indexOf(wit) != -1)
            continue;
        if (!core()->widgetDataBase()->isContainer(wit) &&
             wit != mainContainer())
            continue;

        // the rectangles of all ancestors of the container must contain the insert position
        QWidget *w = wit;
        while (w && !w->isWindow()) {
            if (!w->rect().contains((w->mapFromGlobal(pos))))
                break;
            w = w->parentWidget();
        }
        if (!(w == 0 || w->isWindow()))
            continue; // we did not get through the full while loop

        int wd = widgetDepth(wit);
        if (wd == depth && container) {
            if (wit->parentWidget()->children().indexOf(wit) >
                 container->parentWidget()->children().indexOf(container))
                wd++;
        }
        if (wd > depth && !isChildOf(wit, notParentOf)) {
            depth = wd;
            container = wit;
        }
    }
    return container;
}

QWidgetList FormWindow::selectedWidgets() const
{
    return m_selection->selectedWidgets();
}

void FormWindow::selectWidgets()
{
    bool selectionChanged = false;
    const QWidgetList l = qFindChildren<QWidget*>(mainContainer());
    QListIterator <QWidget*> it(l);
    const QRect selRect(mapToGlobal(m_currRect.topLeft()), m_currRect.size());
    while (it.hasNext()) {
        QWidget *w = it.next();
        if (w->isVisibleTo(this) && isManaged(w)) {
            const QPoint p = w->mapToGlobal(QPoint(0,0));
            const QRect r(p, w->size());
            if (r.intersects(selRect) && !r.contains(selRect) && trySelectWidget(w, true))
                selectionChanged = true;
        }
    }

    if (selectionChanged)
        emitSelectionChanged();
}

bool FormWindow::handleKeyPressEvent(QWidget *widget, QWidget *, QKeyEvent *e)
{
    if (qobject_cast<const FormWindow*>(widget) || qobject_cast<const QMenu*>(widget))
        return false;

    e->accept(); // we always accept!

    switch (e->key()) {
        default: break; // we don't care about the other keys

        case Qt::Key_Delete:
        case Qt::Key_Backspace:
            if (e->modifiers() == Qt::NoModifier)
                deleteWidgets();
            break;

        case Qt::Key_Tab:
            if (e->modifiers() == Qt::NoModifier)
                cursor()->movePosition(QDesignerFormWindowCursorInterface::Next);
            break;

        case Qt::Key_Backtab:
            if (e->modifiers() == Qt::NoModifier)
                cursor()->movePosition(QDesignerFormWindowCursorInterface::Prev);
            break;

        case Qt::Key_Left:
        case Qt::Key_Right:
        case Qt::Key_Up:
        case Qt::Key_Down:
            handleArrowKeyEvent(e->key(), e->modifiers());
            break;
    }

    return true;
}

int FormWindow::getValue(const QRect &rect, int key, bool size) const
{
    if (size) {
        if (key == Qt::Key_Left || key == Qt::Key_Right)
            return rect.width();
        return rect.height();
    }
    if (key == Qt::Key_Left || key == Qt::Key_Right)
        return rect.x();
    return rect.y();
}

int FormWindow::calcValue(int val, bool forward, bool snap, int snapOffset) const
{
    if (snap) {
        const int rest = val % snapOffset;
        if (rest) {
            const int offset = forward ? snapOffset : 0;
            const int newOffset = rest < 0 ? offset - snapOffset : offset;
            return val + newOffset - rest;
        }
        return (forward ? val + snapOffset : val - snapOffset);
    }
    return (forward ? val + 1 : val - 1);
}

// ArrowKeyOperation: Stores a keyboard move or resize (Shift pressed)
// operation.
struct ArrowKeyOperation {
    ArrowKeyOperation() : resize(false), distance(0), arrowKey(Qt::Key_Left) {}

    QRect apply(const QRect &in) const;

    bool resize; // Resize: Shift-Key->drag bottom/right corner, else just move
    int distance;
    int arrowKey;
};

} // namespace

QT_END_NAMESPACE
Q_DECLARE_METATYPE(qdesigner_internal::ArrowKeyOperation)
QT_BEGIN_NAMESPACE

namespace qdesigner_internal {

QRect ArrowKeyOperation::apply(const QRect &rect) const
{
    QRect r = rect;
    if (resize) {
        if (arrowKey == Qt::Key_Left || arrowKey == Qt::Key_Right)
            r.setWidth(r.width() + distance);
        else
            r.setHeight(r.height() + distance);
    } else {
        if (arrowKey == Qt::Key_Left || arrowKey == Qt::Key_Right)
            r.moveLeft(r.x() + distance);
        else
            r.moveTop(r.y() + distance);
    }
    return r;
}

QDebug operator<<(QDebug in, const ArrowKeyOperation &op)
{
    in.nospace() << "Resize=" << op.resize << " dist=" << op.distance << " Key=" << op.arrowKey << ' ';
    return in;
}

// ArrowKeyPropertyHelper: Applies a struct ArrowKeyOperation
// (stored as new value) to a list of widgets using to calculate the
// changed geometry of the widget in setValue(). Thus, the 'newValue'
// of the property command is the relative move distance, which is the same
// for all widgets (although resulting in different geometries for the widgets).
// The command merging can then work as it would when applying the same text
// to all QLabels.

class ArrowKeyPropertyHelper : public PropertyHelper {
public:
    ArrowKeyPropertyHelper(QObject* o, SpecialProperty sp,
                       QDesignerPropertySheetExtension *s, int i) :
                       PropertyHelper(o, sp, s, i) {}

    virtual Value setValue(QDesignerFormWindowInterface *fw, const QVariant &value, bool changed, unsigned subPropertyMask);
};

PropertyHelper::Value ArrowKeyPropertyHelper::setValue(QDesignerFormWindowInterface *fw, const QVariant &value, bool changed, unsigned subPropertyMask)
{
    // Apply operation to obtain the new geometry value.
    QWidget *w = qobject_cast<QWidget*>(object());
    const ArrowKeyOperation operation = qvariant_cast<ArrowKeyOperation>(value);
    const QRect newGeom = operation.apply(w->geometry());
    return PropertyHelper::setValue(fw, QVariant(newGeom), changed, subPropertyMask);
}

// ArrowKeyPropertyCommand: Helper factory overwritten to create
// ArrowKeyPropertyHelper and a merge operation that merges values of
// the same direction.
class ArrowKeyPropertyCommand: public SetPropertyCommand {
public:
    explicit ArrowKeyPropertyCommand(QDesignerFormWindowInterface *fw,
                                     QUndoCommand *p = 0);

    void init(QWidgetList &l, const ArrowKeyOperation &op);

protected:
    virtual PropertyHelper *createPropertyHelper(QObject *o, SpecialProperty sp,
                                                 QDesignerPropertySheetExtension *s, int i) const
        { return new ArrowKeyPropertyHelper(o, sp, s, i); }
    virtual QVariant mergeValue(const QVariant &newValue);
};

ArrowKeyPropertyCommand::ArrowKeyPropertyCommand(QDesignerFormWindowInterface *fw,
                                                 QUndoCommand *p) :
    SetPropertyCommand(fw, p)
{
    static const int mid = qRegisterMetaType<qdesigner_internal::ArrowKeyOperation>();
    Q_UNUSED(mid)
}

void ArrowKeyPropertyCommand::init(QWidgetList &l, const ArrowKeyOperation &op)
{
    QObjectList ol;
    foreach(QWidget *w, l)
        ol.push_back(w);
    SetPropertyCommand::init(ol, QLatin1String("geometry"), qVariantFromValue(op));

    setText(op.resize ? FormWindow::tr("Key Resize") : FormWindow::tr("Key Move"));
}

QVariant ArrowKeyPropertyCommand::mergeValue(const QVariant &newMergeValue)
{
    // Merge move operations of the same arrow key
    if (!qVariantCanConvert<ArrowKeyOperation>(newMergeValue))
        return QVariant();
    ArrowKeyOperation mergedOperation = qvariant_cast<ArrowKeyOperation>(newValue());
    const ArrowKeyOperation newMergeOperation = qvariant_cast<ArrowKeyOperation>(newMergeValue);
    if (mergedOperation.resize != newMergeOperation.resize || mergedOperation.arrowKey != newMergeOperation.arrowKey)
        return QVariant();
    mergedOperation.distance += newMergeOperation.distance;
    return qVariantFromValue(mergedOperation);
}

void FormWindow::handleArrowKeyEvent(int key, Qt::KeyboardModifiers modifiers)
{
    const QDesignerFormWindowCursorInterface *c = cursor();
    if (!c->hasSelection())
        return;

    QWidgetList selection;

    // check if a laid out widget is selected
    const int count = c->selectedWidgetCount();
    for (int index = 0; index < count; ++index) {
        QWidget *w = c->selectedWidget(index);
        if (!LayoutInfo::isWidgetLaidout(m_core, w))
            selection.append(w);
    }

    if (selection.isEmpty())
        return;

    QWidget *current = c->current();
    if (!current || LayoutInfo::isWidgetLaidout(m_core, current)) {
        current = selection.first();
    }

    const bool size = modifiers & Qt::ShiftModifier;

    const bool snap = !(modifiers & Qt::ControlModifier);
    const bool forward = (key == Qt::Key_Right || key == Qt::Key_Down);
    const int snapPoint = (key == Qt::Key_Left || key == Qt::Key_Right) ? grid().x() : grid().y();

    const int oldValue = getValue(current->geometry(), key, size);

    const int newValue = calcValue(oldValue, forward, snap, snapPoint);

    ArrowKeyOperation operation;
    operation.resize = modifiers & Qt::ShiftModifier;
    operation.distance = newValue - oldValue;
    operation.arrowKey = key;

    ArrowKeyPropertyCommand *cmd = new ArrowKeyPropertyCommand(this);
    cmd->init(selection, operation);
    m_undoStack.push(cmd);
}

bool FormWindow::handleKeyReleaseEvent(QWidget *, QWidget *, QKeyEvent *e)
{
    e->accept();
    return true;
}

void FormWindow::selectAll()
{
    bool selectionChanged = false;
    foreach (QWidget *widget, m_widgets) {
        if (widget->isVisibleTo(this) && trySelectWidget(widget, true))
            selectionChanged = true;
    }
    if (selectionChanged)
        emitSelectionChanged();
}

void FormWindow::createLayout(int type, QWidget *container)
{
    if (container) {
        layoutContainer(container, type);
    } else {
        LayoutCommand *cmd = new LayoutCommand(this);
        cmd->init(mainContainer(), selectedWidgets(), static_cast<LayoutInfo::Type>(type));
        commandHistory()->push(cmd);
    }
}

void FormWindow::morphLayout(QWidget *container, int newType)
{
    MorphLayoutCommand *cmd = new MorphLayoutCommand(this);
    if (cmd->init(container, newType)) {
        commandHistory()->push(cmd);
    } else {
        qDebug() << "** WARNING Unable to morph layout.";
        delete cmd;
    }
}

void FormWindow::deleteWidgets()
{
    QWidgetList selection = selectedWidgets();
    simplifySelection(&selection);

    deleteWidgetList(selection);
}

QString FormWindow::fileName() const
{
    return m_fileName;
}

void FormWindow::setFileName(const QString &fileName)
{
    if (m_fileName == fileName)
        return;

    m_fileName = fileName;
    emit fileNameChanged(fileName);
}

QString FormWindow::contents() const
{
    QBuffer b;
    if (!mainContainer() || !b.open(QIODevice::WriteOnly))
        return QString();

    QDesignerResource resource(const_cast<FormWindow*>(this));
    resource.save(&b, mainContainer());

    return QString::fromUtf8(b.buffer());
}

void FormWindow::copy()
{
    QBuffer b;
    if (!b.open(QIODevice::WriteOnly))
        return;

    FormBuilderClipboard clipboard;
    QDesignerResource resource(this);
    resource.setSaveRelative(false);
    clipboard.m_widgets = selectedWidgets();
    simplifySelection(&clipboard.m_widgets);
    resource.copy(&b, clipboard);

    qApp->clipboard()->setText(QString::fromUtf8(b.buffer()), QClipboard::Clipboard);
}

void FormWindow::cut()
{
    copy();
    deleteWidgets();
}

// for cases like QMainWindow (central widget is an inner container) or QStackedWidget (page is an inner container)
QWidget *FormWindow::innerContainer(QWidget *outerContainer) const
{
    if (m_core->widgetDataBase()->isContainer(outerContainer))
        if (const QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(m_core->extensionManager(), outerContainer)) {
            const int currentIndex = container->currentIndex();
            return currentIndex >= 0 ?
                        container->widget(currentIndex) :
                        static_cast<QWidget *>(0);
        }
    return outerContainer;
}

QWidget *FormWindow::containerForPaste() const
{
    QWidget *w = mainContainer();
    if (!w)
        return 0;
    do {
        // Try to find a close parent, for example a non-laid-out
        // QFrame/QGroupBox when a widget within it is selected.
        QWidgetList selection = selectedWidgets();
        if (selection.empty())
            break;
        simplifySelection(&selection);

        QWidget *containerOfW = findContainer(selection.first(), /* exclude layouts */ true);
        if (!containerOfW || containerOfW == mainContainer())
            break;
        // No layouts, must be container. No empty page-based containers.
        containerOfW = innerContainer(containerOfW);
        if (!containerOfW)
            break;
        if (LayoutInfo::layoutType(m_core, containerOfW) != LayoutInfo::NoLayout || !m_core->widgetDataBase()->isContainer(containerOfW))
            break;
        w = containerOfW;
    } while (false);
    // First check for layout (note that it does not cover QMainWindow
    // and the like as the central widget has the layout).

    w = innerContainer(w);
    if (!w)
        return 0;
    if (LayoutInfo::layoutType(m_core, w) != LayoutInfo::NoLayout)
        return 0;
    // Go up via container extension (also includes step from QMainWindow to its central widget)
    w = m_core->widgetFactory()->containerOfWidget(w);
    if (w == 0 || LayoutInfo::layoutType(m_core, w) != LayoutInfo::NoLayout)
        return 0;

    if (debugFormWindow)
        qDebug() <<"containerForPaste() " <<  w;
    return w;
}

void FormWindow::paste()
{
    paste(PasteAll);
}

// Construct DomUI from clipboard (paste) and determine number of widgets/actions.
static inline DomUI *domUIFromClipboard(int *widgetCount, int *actionCount)
{
    *widgetCount = *actionCount = 0;
    const QString clipboardText = qApp->clipboard()->text();
    if (clipboardText.isEmpty() || clipboardText.indexOf(QLatin1Char('<')) == -1)
        return 0;

    QXmlStreamReader reader(clipboardText);
    DomUI *ui = 0;
    const QString uiElement = QLatin1String("ui");
    while (!reader.atEnd()) {
        if (reader.readNext() == QXmlStreamReader::StartElement) {
            if (reader.name().compare(uiElement, Qt::CaseInsensitive) == 0 && !ui) {
                ui = new DomUI();
                ui->read(reader);
                break;
            } else {
                reader.raiseError(QCoreApplication::translate("FormWindow", "Unexpected element <%1>").arg(reader.name().toString()));
            }
        }
    }
    if (reader.hasError()) {
        delete ui;
        ui = 0;
        designerWarning(QCoreApplication::translate("FormWindow", "Error while pasting clipboard contents at line %1, column %2: %3").
                        arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.errorString()));
        return 0;
    }

    if (const DomWidget *topLevel = ui->elementWidget()) {
        *widgetCount = topLevel->elementWidget().size();
        *actionCount = topLevel->elementAction().size();
    }
    if (*widgetCount == 0 && *actionCount == 0) {
        delete ui;
        return 0;
    }
    return ui;
}

static inline QString pasteCommandDescription(int widgetCount, int actionCount)
{
    if (widgetCount == 0)
        return FormWindow::tr("Paste %n action(s)", 0, actionCount);
    if (actionCount == 0)
        return FormWindow::tr("Paste %n widget(s)", 0, widgetCount);
    return FormWindow::tr("Paste (%1 widgets, %2 actions)").arg(widgetCount).arg(actionCount);
}

static void positionPastedWidgetsAtMousePosition(FormWindow *fw, const QPoint &contextMenuPosition, QWidget *parent, const QWidgetList &l)
{
    // Try to position pasted widgets at mouse position (current mouse position for Ctrl-V or position of context menu)
    // if it fits. If it is completely outside, force it to 0,0
    // If it fails, the old coordinates relative to the previous parent will be used.
    QPoint currentPos = contextMenuPosition.x() >=0 ? parent->mapFrom(fw, contextMenuPosition) : parent->mapFromGlobal(QCursor::pos());
    const Grid &grid = fw->designerGrid();
    QPoint cursorPos = grid.snapPoint(currentPos);
    const QRect parentGeometry = QRect(QPoint(0, 0), parent->size());
    const bool outside = !parentGeometry.contains(cursorPos);
    if (outside)
        cursorPos = grid.snapPoint(QPoint(0, 0));
    // Determine area of pasted widgets
    QRect pasteArea;
    const QWidgetList::const_iterator lcend = l.constEnd();
    for (QWidgetList::const_iterator it = l.constBegin(); it != lcend; ++it)
        pasteArea =pasteArea.isNull() ? (*it)->geometry() : pasteArea.united((*it)->geometry());

    // Mouse on some child? (try to position bottomRight on a free spot to
    // get the stacked-offset effect of Designer 4.3, that is, offset by grid if Ctrl-V is pressed continuously
    do {
        const QPoint bottomRight = cursorPos + QPoint(pasteArea.width(), pasteArea.height()) - QPoint(1, 1);
        if (bottomRight.y() > parentGeometry.bottom() || parent->childAt(bottomRight) == 0)
            break;
        cursorPos += QPoint(grid.deltaX(), grid.deltaY());
    } while (true);
    // Move.
    const QPoint offset = cursorPos - pasteArea.topLeft();
    for (QWidgetList::const_iterator it = l.constBegin(); it != lcend; ++it)
        (*it)->move((*it)->pos() + offset);
}

void FormWindow::paste(PasteMode pasteMode)
{
    // Avoid QDesignerResource constructing widgets that are not used as
    // QDesignerResource manages the widgets it creates (creating havoc if one remains unused)
    DomUI *ui = 0;
    do {
        int widgetCount;
        int actionCount;
        ui = domUIFromClipboard(&widgetCount, &actionCount);
        if (!ui)
            break;

        // Check for actions
        if (pasteMode == PasteActionsOnly)
            if (widgetCount != 0 || actionCount == 0)
                break;

        // Check for widgets: need a container
        QWidget *pasteContainer = widgetCount ? containerForPaste() : 0;
        if (widgetCount && pasteContainer == 0) {

            const QString message = tr("Cannot paste widgets. Designer could not find a container "
                                       "without a layout to paste into.");
            const QString infoMessage = tr("Break the layout of the "
                                       "container you want to paste into, select this container "
                                       "and then paste again.");
            core()->dialogGui()->message(this, QDesignerDialogGuiInterface::FormEditorMessage, QMessageBox::Information,
                                         tr("Paste error"), message, infoMessage, QMessageBox::Ok);
            break;
        }

        QDesignerResource resource(this);
        // Note that the widget factory must be able to locate the
        // form window (us) via parent, otherwise, it will not able to construct QLayoutWidgets
        // (It will then default to widgets) among other issues.
        const FormBuilderClipboard clipboard = resource.paste(ui, pasteContainer, this);

        clearSelection(false);
        // Create command sequence
        beginCommand(pasteCommandDescription(widgetCount, actionCount));

        if (widgetCount) {
            positionPastedWidgetsAtMousePosition(this,  m_contextMenuPosition, pasteContainer, clipboard.m_widgets);
            foreach (QWidget *w, clipboard.m_widgets) {
                InsertWidgetCommand *cmd = new InsertWidgetCommand(this);
                cmd->init(w);
                m_undoStack.push(cmd);
                selectWidget(w);
            }
        }

        if (actionCount)
            foreach (QAction *a, clipboard.m_actions) {
                ensureUniqueObjectName(a);
                AddActionCommand *cmd = new AddActionCommand(this);
                cmd->init(a);
                m_undoStack.push(cmd);
            }
        endCommand();
    } while (false);
    delete ui;
}

// Draw a dotted frame around containers
bool FormWindow::frameNeeded(QWidget *w) const
{
    if (!core()->widgetDataBase()->isContainer(w))
        return false;
    if (qobject_cast<QGroupBox *>(w))
        return false;
    if (qobject_cast<QToolBox *>(w))
        return false;
    if (qobject_cast<QTabWidget *>(w))
        return false;
    if (qobject_cast<QStackedWidget *>(w))
        return false;
    if (qobject_cast<QDockWidget *>(w))
        return false;
    if (qobject_cast<QDesignerWidget *>(w))
        return false;
    if (qobject_cast<QMainWindow *>(w))
        return false;
    if (qobject_cast<QDialog *>(w))
        return false;
    if (qobject_cast<QLayoutWidget *>(w))
        return false;
    return true;
}

bool FormWindow::eventFilter(QObject *watched, QEvent *event)
{
    const bool ret = FormWindowBase::eventFilter(watched, event);
    if (event->type() != QEvent::Paint)
        return ret;

    Q_ASSERT(watched->isWidgetType());
    QWidget *w = static_cast<QWidget *>(watched);
    QPaintEvent *pe = static_cast<QPaintEvent*>(event);
    const QRect widgetRect = w->rect();
    const QRect paintRect =  pe->rect();
    // Does the paint rectangle touch the borders of the widget rectangle
    if (paintRect.x()     > widgetRect.x()     && paintRect.y()      > widgetRect.y() &&
        paintRect.right() < widgetRect.right() && paintRect.bottom() < widgetRect.bottom())
        return ret;
    QPainter p(w);
    const QPen pen(QColor(0, 0, 0, 32), 0, Qt::DotLine);
    p.setPen(pen);
    p.setBrush(QBrush(Qt::NoBrush));
    p.drawRect(widgetRect.adjusted(0, 0, -1, -1));
    return ret;
}

void FormWindow::manageWidget(QWidget *w)
{
    if (isManaged(w))
        return;

    Q_ASSERT(qobject_cast<QMenu*>(w) == 0);

    if (w->hasFocus())
        setFocus();

    core()->metaDataBase()->add(w);

    m_insertedWidgets.insert(w);
    m_widgets.append(w);

#ifndef QT_NO_CURSOR
    setCursorToAll(Qt::ArrowCursor, w);
#endif

    emit changed();
    emit widgetManaged(w);

    if (frameNeeded(w))
        w->installEventFilter(this);
}

void FormWindow::unmanageWidget(QWidget *w)
{
    if (!isManaged(w))
        return;

    m_selection->removeWidget(w);

    emit aboutToUnmanageWidget(w);

    if (w == m_currentWidget)
        setCurrentWidget(mainContainer());

    core()->metaDataBase()->remove(w);

    m_insertedWidgets.remove(w);
    m_widgets.removeAt(m_widgets.indexOf(w));

    emit changed();
    emit widgetUnmanaged(w);

    if (frameNeeded(w))
        w->removeEventFilter(this);
}

bool FormWindow::isManaged(QWidget *w) const
{
    return m_insertedWidgets.contains(w);
}

void FormWindow::breakLayout(QWidget *w)
{
    if (w == this)
        w = mainContainer();
    // Find the first-order managed child widgets
    QWidgetList widgets;

    const QObjectList children = w->children();
    const QObjectList::const_iterator cend = children.constEnd();
    const QDesignerMetaDataBaseInterface *mdb = core()->metaDataBase();
    for (QObjectList::const_iterator it =  children.constBegin(); it != cend; ++it)
        if ( (*it)->isWidgetType())  {
            QWidget *w = static_cast<QWidget*>(*it);
            if (mdb->item(w))
                widgets.push_back(w);
        }

    BreakLayoutCommand *cmd = new BreakLayoutCommand(this);
    cmd->init(widgets, w);
    commandHistory()->push(cmd);
    clearSelection(false);
}

void FormWindow::beginCommand(const QString &description)
{
    m_undoStack.beginMacro(description);
}

void FormWindow::endCommand()
{
    m_undoStack.endMacro();
}

void FormWindow::raiseWidgets()
{
    QWidgetList widgets = selectedWidgets();
    simplifySelection(&widgets);

    if (widgets.isEmpty())
        return;

    beginCommand(tr("Raise widgets"));
    foreach (QWidget *widget, widgets) {
        RaiseWidgetCommand *cmd = new RaiseWidgetCommand(this);
        cmd->init(widget);
        m_undoStack.push(cmd);
    }
    endCommand();
}

void FormWindow::lowerWidgets()
{
    QWidgetList widgets = selectedWidgets();
    simplifySelection(&widgets);

    if (widgets.isEmpty())
        return;

    beginCommand(tr("Lower widgets"));
    foreach (QWidget *widget, widgets) {
        LowerWidgetCommand *cmd = new LowerWidgetCommand(this);
        cmd->init(widget);
        m_undoStack.push(cmd);
    }
    endCommand();
}

bool FormWindow::handleMouseButtonDblClickEvent(QWidget *w, QWidget *managedWidget, QMouseEvent *e)
{
    if (debugFormWindow)
        qDebug() << "handleMouseButtonDblClickEvent:" << w << ',' << managedWidget << "state=" << m_mouseState;

    e->accept();

    // Might be out of sync due cycling of the parent selection
    // In that case, do nothing
    if (isWidgetSelected(managedWidget))
        emit activated(managedWidget);

    m_mouseState = MouseDoubleClicked;
    return true;
}


QMenu *FormWindow::initializePopupMenu(QWidget *managedWidget)
{
    if (!isManaged(managedWidget) || currentTool())
        return 0;

    // Make sure the managedWidget is selected and current since
    // the SetPropertyCommands must use the right reference
    // object obtained from the property editor for the property group
    // of a multiselection to be correct.
    const bool selected = isWidgetSelected(managedWidget);
    bool update = false;
    if (selected == false) {
        clearObjectInspectorSelection(m_core); // We might have a toolbar or non-widget selected in the object inspector.
        clearSelection(false);
        update = trySelectWidget(managedWidget, true);
        raiseChildSelections(managedWidget); // raise selections and select widget
    } else {
        update = setCurrentWidget(managedWidget);
    }

    if (update) {
        emitSelectionChanged();
        QMetaObject::invokeMethod(core()->formWindowManager(), "slotUpdateActions");
    }

    QWidget *contextMenuWidget = 0;

    if (isMainContainer(managedWidget)) { // press on a child widget
        contextMenuWidget = mainContainer();
    } else {  // press on a child widget
        // if widget is laid out, find the first non-laid out super-widget
        QWidget *realWidget = managedWidget; // but store the original one
        QMainWindow *mw = qobject_cast<QMainWindow*>(mainContainer());

        if (mw && mw->centralWidget() == realWidget) {
            contextMenuWidget = managedWidget;
        } else {
            contextMenuWidget = realWidget;
        }
    }

    if (!contextMenuWidget)
        return 0;

    QMenu *contextMenu = createPopupMenu(contextMenuWidget);
    if (!contextMenu)
        return 0;

    emit contextMenuRequested(contextMenu, contextMenuWidget);
    return contextMenu;
}

bool FormWindow::handleContextMenu(QWidget *, QWidget *managedWidget, QContextMenuEvent *e)
{
    QMenu *contextMenu = initializePopupMenu(managedWidget);
    if (!contextMenu)
        return false;
    const QPoint globalPos = e->globalPos();
    m_contextMenuPosition = mapFromGlobal (globalPos);
    contextMenu->exec(globalPos);
    delete contextMenu;
    e->accept();
    m_contextMenuPosition = QPoint(-1, -1);
    return true;
}

void FormWindow::setContents(QIODevice *dev)
{
    UpdateBlocker ub(this);
    clearSelection();
    m_selection->clearSelectionPool();
    m_insertedWidgets.clear();
    m_widgets.clear();
    // The main container is cleared as otherwise
    // the names of the newly loaded objects will be unified.
    clearMainContainer();
    emit changed();

    QDesignerResource r(this);
    QWidget *w = r.load(dev, formContainer());
    setMainContainer(w);
    emit changed();
}

void FormWindow::setContents(const QString &contents)
{
    QByteArray data = contents.toUtf8();
    QBuffer b(&data);
    if (b.open(QIODevice::ReadOnly))
        setContents(&b);
}

void FormWindow::layoutContainer(QWidget *w, int type)
{
    if (w == this)
        w = mainContainer();

    w = core()->widgetFactory()->containerOfWidget(w);

    const QObjectList l = w->children();
    if (l.isEmpty())
        return;
    // find managed widget children
    QWidgetList widgets;
    const QObjectList::const_iterator ocend = l.constEnd();
    for (QObjectList::const_iterator it = l.constBegin(); it != l.constEnd(); ++it)
        if ( (*it)->isWidgetType() ) {
            QWidget *widget = static_cast<QWidget*>(*it);
            if (widget->isVisibleTo(this) && isManaged(widget))
                widgets.append(widget);
        }

    LayoutCommand *cmd = new LayoutCommand(this);
    cmd->init(mainContainer(), widgets, static_cast<LayoutInfo::Type>(type), w);
    clearSelection(false);
    commandHistory()->push(cmd);
}

bool FormWindow::hasInsertedChildren(QWidget *widget) const // ### move
{
    if (QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), widget)) {
        const int index = container->currentIndex();
        if (index < 0)
            return false;
        widget = container->widget(index);
    }

    const QWidgetList l = widgets(widget);

    foreach (QWidget *child, l) {
        if (isManaged(child) && !LayoutInfo::isWidgetLaidout(core(), child) && child->isVisibleTo(const_cast<FormWindow*>(this)))
            return true;
    }

    return false;
}

// "Select Ancestor" sub menu code
void FormWindow::slotSelectWidget(QAction *a)
{
    if (QWidget *w = qvariant_cast<QWidget*>(a->data()))
        selectSingleWidget(w);
}

static inline QString objectNameOf(const QWidget *w)
{
    if (const QLayoutWidget *lw = qobject_cast<const QLayoutWidget *>(w)) {
        const QLayout *layout = lw->layout();
        const QString rc = layout->objectName();
        if (!rc.isEmpty())
            return rc;
        // Fall thru for 4.3 forms which have a name on the widget: Display the class name
        return QString::fromUtf8(layout->metaObject()->className());
    }
    return  w->objectName();
}

QAction *FormWindow::createSelectAncestorSubMenu(QWidget *w)
{
    // Find the managed, unselected parents
    QWidgetList parents;
    QWidget *mc = mainContainer();
    for (QWidget *p = w->parentWidget(); p && p != mc; p = p->parentWidget())
        if (isManaged(p) && !isWidgetSelected(p))
            parents.push_back(p);
    if (parents.empty())
        return 0;
    // Create a submenu listing the managed, unselected parents
    QMenu *menu = new QMenu;
    QActionGroup *ag = new QActionGroup(menu);
    QObject::connect(ag, SIGNAL(triggered(QAction*)), this, SLOT(slotSelectWidget(QAction*)));
    const int size = parents.size();
    for (int i = 0; i < size; i++) {
        QWidget *w = parents.at(i);
        QAction *a = ag->addAction(objectNameOf(w));
        a->setData(qVariantFromValue(w));
        menu->addAction(a);
    }
    QAction *ma = new QAction(tr("Select Ancestor"), 0);
    ma->setMenu(menu);
    return ma;
}

QMenu *FormWindow::createPopupMenu(QWidget *w)
{
    QMenu *popup = createExtensionTaskMenu(this, w, true);
    if (!popup)
        popup = new QMenu;
    // if w doesn't have a QDesignerTaskMenu as a child create one and make it a child.
    // insert actions from QDesignerTaskMenu

    QDesignerFormWindowManagerInterface *manager = core()->formWindowManager();
    const bool isFormWindow = qobject_cast<const FormWindow*>(w);

    // Check for special containers and obtain the page menu from them to add layout actions.
    if (!isFormWindow) {
        if (QStackedWidget *stackedWidget  = qobject_cast<QStackedWidget*>(w)) {
            QStackedWidgetEventFilter::addStackedWidgetContextMenuActions(stackedWidget, popup);
        } else if (QTabWidget *tabWidget = qobject_cast<QTabWidget*>(w)) {
            QTabWidgetEventFilter::addTabWidgetContextMenuActions(tabWidget, popup);
        } else if (QToolBox *toolBox = qobject_cast<QToolBox*>(w)) {
            QToolBoxHelper::addToolBoxContextMenuActions(toolBox, popup);
        }

        if (manager->actionLower()->isEnabled()) {
            popup->addAction(manager->actionLower());
            popup->addAction(manager->actionRaise());
            popup->addSeparator();
        }
        popup->addAction(manager->actionCut());
        popup->addAction(manager->actionCopy());
    }

    popup->addAction(manager->actionPaste());

    if (QAction *selectAncestorAction = createSelectAncestorSubMenu(w))
        popup->addAction(selectAncestorAction);
    popup->addAction(manager->actionSelectAll());

    if (!isFormWindow) {
        popup->addAction(manager->actionDelete());
    }

    popup->addSeparator();
    QMenu *layoutMenu = popup->addMenu(tr("Lay out"));
    layoutMenu->addAction(manager->actionAdjustSize());
    layoutMenu->addAction(manager->actionHorizontalLayout());
    layoutMenu->addAction(manager->actionVerticalLayout());
    if (!isFormWindow) {
        layoutMenu->addAction(manager->actionSplitHorizontal());
        layoutMenu->addAction(manager->actionSplitVertical());
    }
    layoutMenu->addAction(manager->actionGridLayout());
    layoutMenu->addAction(manager->actionFormLayout());
    layoutMenu->addAction(manager->actionBreakLayout());
    layoutMenu->addAction(manager->actionSimplifyLayout());

    return popup;
}

void FormWindow::resizeEvent(QResizeEvent *e)
{
    m_geometryChangedTimer->start(10);

    QWidget::resizeEvent(e);
}

/*!
  Maps \a pos in \a w's coordinates to the form's coordinate system.

  This is the equivalent to mapFromGlobal(w->mapToGlobal(pos)) but
  avoids the two roundtrips to the X-Server on Unix/X11.
 */
QPoint FormWindow::mapToForm(const QWidget *w, const QPoint &pos) const
{
    QPoint p = pos;
    const QWidget* i = w;
    while (i && !i->isWindow() && !isMainContainer(i)) {
        p = i->mapToParent(p);
        i = i->parentWidget();
    }

    return mapFromGlobal(w->mapToGlobal(pos));
}

bool FormWindow::canBeBuddy(QWidget *w) const // ### rename me.
{
    if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), w)) {
        const int index = sheet->indexOf(QLatin1String("focusPolicy"));
        if (index != -1) {
            bool ok = false;
            const Qt::FocusPolicy q = static_cast<Qt::FocusPolicy>(Utils::valueOf(sheet->property(index), &ok));
            return ok && q != Qt::NoFocus;
        }
    }

    return false;
}

QWidget *FormWindow::findContainer(QWidget *w, bool excludeLayout) const
{
    if (!isChildOf(w, this)
        || const_cast<const QWidget *>(w) == this)
        return 0;

    QDesignerWidgetFactoryInterface *widgetFactory = core()->widgetFactory();
    QDesignerWidgetDataBaseInterface *widgetDataBase = core()->widgetDataBase();
    QDesignerMetaDataBaseInterface *metaDataBase = core()->metaDataBase();

    QWidget *container = widgetFactory->containerOfWidget(mainContainer()); // default parent for new widget is the formwindow
    if (!isMainContainer(w)) { // press was not on formwindow, check if we can find another parent
        while (w) {
            if (qobject_cast<InvisibleWidget*>(w) || !metaDataBase->item(w)) {
                w = w->parentWidget();
                continue;
            }

            const bool isContainer =  widgetDataBase->isContainer(w, true) || w == mainContainer();

            if (!isContainer || (excludeLayout && qobject_cast<QLayoutWidget*>(w))) { // ### skip QSplitter
                w = w->parentWidget();
            } else {
                container = w;
                break;
            }
        }
    }

    return container;
}

void FormWindow::simplifySelection(QWidgetList *sel) const
{
    if (sel->size() < 2)
        return;
    // Figure out which widgets should be removed from selection.
    // We want to remove those whose parent widget is also in the
    // selection (because the child widgets are contained by
    // their parent, they shouldn't be in the selection --
    // they are "implicitly" selected).
    QWidget *mainC = mainContainer(); // Quick check for main container first
    if (sel->contains(mainC)) {
        sel->clear();
        sel->push_back(mainC);
        return;
    }
    typedef QVector<QWidget *> WidgetVector;
    WidgetVector toBeRemoved;
    toBeRemoved.reserve(sel->size());
    const QWidgetList::const_iterator scend = sel->constEnd();
    for (QWidgetList::const_iterator it = sel->constBegin(); it != scend; ++it) {
        QWidget *child = *it;
        for (QWidget *w = child; true ; ) { // Is any of the parents also selected?
            QWidget *parent = w->parentWidget();
            if (!parent || parent == mainC)
                break;
            if (sel->contains(parent)) {
                toBeRemoved.append(child);
                break;
            }
            w = parent;
         }
    }
    // Now we can actually remove the widgets that were marked
    // for removal in the previous pass.
    if (!toBeRemoved.isEmpty()) {
        const WidgetVector::const_iterator rcend = toBeRemoved.constEnd();
        for (WidgetVector::const_iterator it = toBeRemoved.constBegin(); it != rcend; ++it)
            sel->removeAll(*it);
    }
}

FormWindow *FormWindow::findFormWindow(QWidget *w)
{
    return qobject_cast<FormWindow*>(QDesignerFormWindowInterface::findFormWindow(w));
}

bool FormWindow::isDirty() const
{
    return m_undoStack.isDirty();
}

void FormWindow::setDirty(bool dirty)
{
    m_undoStack.setDirty(dirty);
}

QWidget *FormWindow::containerAt(const QPoint &pos)
{
    QWidget *widget = widgetAt(pos);
    return findContainer(widget, true);
}

static QWidget *childAt_SkipDropLine(QWidget *w, QPoint pos)
{
    const QObjectList child_list = w->children();
    for (int i = child_list.size() - 1; i >= 0; --i) {
        QObject *child_obj = child_list[i];
        if (qobject_cast<WidgetHandle*>(child_obj) != 0)
            continue;
        QWidget *child = qobject_cast<QWidget*>(child_obj);
        if (!child || child->isWindow() || !child->isVisible() ||
                !child->geometry().contains(pos) || child->testAttribute(Qt::WA_TransparentForMouseEvents))
            continue;
        const QPoint childPos = child->mapFromParent(pos);
        if (QWidget *res = childAt_SkipDropLine(child, childPos))
            return res;
        if (child->testAttribute(Qt::WA_MouseNoMask) || child->mask().contains(pos)
                || child->mask().isEmpty())
            return child;
    }

    return 0;
}

QWidget *FormWindow::widgetAt(const QPoint &pos)
{
    QWidget *w = childAt(pos);
    if (qobject_cast<const WidgetHandle*>(w) != 0)
        w = childAt_SkipDropLine(this, pos);
    return (w == 0 || w == formContainer()) ? this : w;
}

void FormWindow::highlightWidget(QWidget *widget, const QPoint &pos, HighlightMode mode)
{
    Q_ASSERT(widget);

    if (QMainWindow *mainWindow = qobject_cast<QMainWindow*> (widget)) {
        widget = mainWindow->centralWidget();
    }

    QWidget *container = findContainer(widget, false);

    if (container == 0 || core()->metaDataBase()->item(container) == 0)
        return;

    if (QDesignerActionProviderExtension *g = qt_extension<QDesignerActionProviderExtension*>(core()->extensionManager(), container)) {
        if (mode == Restore) {
            g->adjustIndicator(QPoint());
        } else {
            const QPoint pt = widget->mapTo(container, pos);
            g->adjustIndicator(pt);
        }
    } else if (QDesignerLayoutDecorationExtension *g = qt_extension<QDesignerLayoutDecorationExtension*>(core()->extensionManager(), container)) {
        if (mode == Restore) {
            g->adjustIndicator(QPoint(), -1);
        } else {
            const QPoint pt = widget->mapTo(container, pos);
            const int index = g->findItemAt(pt);
            g->adjustIndicator(pt, index);
        }
    }

    QMainWindow *mw = qobject_cast<QMainWindow*> (container);
    if (container == mainContainer() || (mw && mw->centralWidget() && mw->centralWidget() == container))
        return;

    if (mode == Restore) {
        const WidgetPaletteMap::iterator pit = m_palettesBeforeHighlight.find(container);
        if (pit != m_palettesBeforeHighlight.end()) {
            container->setPalette(pit.value().first);
            container->setAutoFillBackground(pit.value().second);
            m_palettesBeforeHighlight.erase(pit);
        }
    } else {
        QPalette p = container->palette();
        if (!m_palettesBeforeHighlight.contains(container)) {
            PaletteAndFill paletteAndFill;
            if (container->testAttribute(Qt::WA_SetPalette))
                paletteAndFill.first = p;
            paletteAndFill.second = container->autoFillBackground();
            m_palettesBeforeHighlight.insert(container, paletteAndFill);
        }

        p.setColor(backgroundRole(), p.midlight().color());
        container->setPalette(p);
        container->setAutoFillBackground(true);
    }
}

QWidgetList FormWindow::widgets(QWidget *widget) const
{
    const  QObjectList children = widget->children();
    if (children.empty())
        return QWidgetList();
    QWidgetList rc;
    const QObjectList::const_iterator cend = children.constEnd();
    for (QObjectList::const_iterator it = children.constBegin(); it != cend; ++it)
        if ((*it)->isWidgetType()) {
            QWidget *w = qobject_cast<QWidget*>(*it);
            if (isManaged(w))
                rc.push_back(w);
        }
    return rc;
}

int FormWindow::toolCount() const
{
    return m_widgetStack->count();
}

QDesignerFormWindowToolInterface *FormWindow::tool(int index) const
{
    return m_widgetStack->tool(index);
}

void FormWindow::registerTool(QDesignerFormWindowToolInterface *tool)
{
    Q_ASSERT(tool != 0);

    m_widgetStack->addTool(tool);

    if (m_mainContainer)
        m_mainContainer->update();
}

void FormWindow::setCurrentTool(int index)
{
    m_widgetStack->setCurrentTool(index);
}

int FormWindow::currentTool() const
{
    return m_widgetStack->currentIndex();
}

bool FormWindow::handleEvent(QWidget *widget, QWidget *managedWidget, QEvent *event)
{
    if (m_widgetStack == 0)
        return false;

    QDesignerFormWindowToolInterface *tool = m_widgetStack->currentTool();
    if (tool == 0)
        return false;

    return tool->handleEvent(widget, managedWidget, event);
}

void FormWindow::initializeCoreTools()
{
    m_widgetEditor = new WidgetEditorTool(this);
    registerTool(m_widgetEditor);
}

void FormWindow::checkSelection()
{
    m_checkSelectionTimer->start(0);
}

void FormWindow::checkSelectionNow()
{
    m_checkSelectionTimer->stop();

    foreach (QWidget *widget, selectedWidgets()) {
        updateSelection(widget);

        if (LayoutInfo::layoutType(core(), widget) != LayoutInfo::NoLayout)
            updateChildSelections(widget);
    }
}

QString FormWindow::author() const
{
    return m_author;
}

QString FormWindow::comment() const
{
     return m_comment;
}

void FormWindow::setAuthor(const QString &author)
{
    m_author = author;
}

void FormWindow::setComment(const QString &comment)
{
    m_comment = comment;
}

void FormWindow::editWidgets()
{
    m_widgetEditor->action()->trigger();
}

QStringList FormWindow::resourceFiles() const
{
    return m_resourceFiles;
}

void FormWindow::addResourceFile(const QString &path)
{
    if (!m_resourceFiles.contains(path)) {
        m_resourceFiles.append(path);
        setDirty(true);
        emit resourceFilesChanged();
    }
}

void FormWindow::removeResourceFile(const QString &path)
{
    if (m_resourceFiles.removeAll(path) > 0) {
        setDirty(true);
        emit resourceFilesChanged();
    }
}

bool FormWindow::blockSelectionChanged(bool b)
{
    const bool blocked = m_blockSelectionChanged;
    m_blockSelectionChanged = b;
    return blocked;
}

void FormWindow::editContents()
{
    const QWidgetList sel = selectedWidgets();
    if (sel.count() == 1) {
        QWidget *widget = sel.first();

        if (QAction *a = preferredEditAction(core(), widget))
            a->trigger();
    }
}

void FormWindow::dragWidgetWithinForm(QWidget *widget, const QRect &targetGeometry, QWidget *targetContainer)
{
    const bool fromLayout = canDragWidgetInLayout(core(), widget);
    const QDesignerLayoutDecorationExtension *targetDeco = qt_extension<QDesignerLayoutDecorationExtension*>(core()->extensionManager(), targetContainer);
    const bool toLayout = targetDeco != 0;

    if (fromLayout) {
        // Drag from Layout: We need to delete the widget properly to store the layout state
        // Do not simplify the layout when dragging onto a layout
        // as this might invalidate the insertion position if it is the same layout
        DeleteWidgetCommand *cmd = new DeleteWidgetCommand(this);
        unsigned deleteFlags = DeleteWidgetCommand::DoNotUnmanage;
        if (toLayout)
            deleteFlags |= DeleteWidgetCommand::DoNotSimplifyLayout;
        cmd->init(widget, deleteFlags);
        commandHistory()->push(cmd);
    }

    if (toLayout) {
        // Drag from form to layout: just insert. Do not manage
        insertWidget(widget, targetGeometry, targetContainer, true);
    } else {
        // into container without layout
        if (targetContainer != widget->parent()) { // different parent
            ReparentWidgetCommand *cmd = new ReparentWidgetCommand(this);
            cmd->init(widget, targetContainer );
            commandHistory()->push(cmd);
        }
        resizeWidget(widget, targetGeometry);
        selectWidget(widget, true);
        widget->show();
    }
}

static Qt::DockWidgetArea detectDropArea(QMainWindow *mainWindow, const QRect &area, const QPoint &drop)
{
    QPoint offset = area.topLeft();
    QRect rect = area;
    rect.moveTopLeft(QPoint(0, 0));
    QPoint point = drop - offset;
    const int x = point.x();
    const int y = point.y();
    const int w = rect.width();
    const int h = rect.height();

    if (rect.contains(point)) {
        bool topRight = false;
        bool topLeft = false;
        if (w * y < h * x)  // top and right, oterwise bottom and left
            topRight = true;
        if (w * y < h * (w - x))  // top and left, otherwise bottom and right
            topLeft = true;

        if (topRight && topLeft)
            return Qt::TopDockWidgetArea;
        else if (topRight && !topLeft)
            return Qt::RightDockWidgetArea;
        else if (!topRight && topLeft)
            return Qt::LeftDockWidgetArea;
        return Qt::BottomDockWidgetArea;
    }

    if (x < 0) {
        if (y < 0)
            return mainWindow->corner(Qt::TopLeftCorner);
        else if (y > h)
            return mainWindow->corner(Qt::BottomLeftCorner);
        else
            return Qt::LeftDockWidgetArea;
    } else if (x > w) {
        if (y < 0)
            return mainWindow->corner(Qt::TopRightCorner);
        else if (y > h)
            return mainWindow->corner(Qt::BottomRightCorner);
        else
            return Qt::RightDockWidgetArea;
    } else {
        if (y < 0)
            return Qt::TopDockWidgetArea;
        else
            return Qt::BottomDockWidgetArea;
    }
    return Qt::LeftDockWidgetArea;
}

bool FormWindow::dropDockWidget(QDesignerDnDItemInterface *item, const QPoint &global_mouse_pos)
{
    DomUI *dom_ui = item->domUi();

    QMainWindow *mw = qobject_cast<QMainWindow *>(mainContainer());
    if (!mw)
        return false;

    QDesignerResource resource(this);
    const FormBuilderClipboard clipboard = resource.paste(dom_ui, mw);
    if (clipboard.m_widgets.size() != 1) // multiple-paste from DomUI not supported yet
        return false;

    QWidget *centralWidget = mw->centralWidget();
    QPoint localPos = centralWidget->mapFromGlobal(global_mouse_pos);
    const QRect centralWidgetAreaRect = centralWidget->rect();
    Qt::DockWidgetArea area = detectDropArea(mw, centralWidgetAreaRect, localPos);

    beginCommand(tr("Drop widget"));

    clearSelection(false);
    highlightWidget(mw, QPoint(0, 0), FormWindow::Restore);

    QWidget *widget = clipboard.m_widgets.first();

    insertWidget(widget, QRect(0, 0, 1, 1), mw);

    selectWidget(widget, true);
    mw->setFocus(Qt::MouseFocusReason); // in case focus was in e.g. object inspector

    core()->formWindowManager()->setActiveFormWindow(this);
    mainContainer()->activateWindow();

    QDesignerPropertySheetExtension *propertySheet = qobject_cast<QDesignerPropertySheetExtension*>(m_core->extensionManager()->extension(widget, Q_TYPEID(QDesignerPropertySheetExtension)));
    if (propertySheet) {
        const QString dockWidgetAreaName = QLatin1String("dockWidgetArea");
        PropertySheetEnumValue e = qvariant_cast<PropertySheetEnumValue>(propertySheet->property(propertySheet->indexOf(dockWidgetAreaName)));
        e.value = area;
        QVariant v;
        qVariantSetValue(v, e);
        SetPropertyCommand *cmd = new SetPropertyCommand(this);
        cmd->init(widget, dockWidgetAreaName, v);
        m_undoStack.push(cmd);
    }

    endCommand();
    return true;
}

bool FormWindow::dropWidgets(const QList<QDesignerDnDItemInterface*> &item_list, QWidget *target,
                             const QPoint &global_mouse_pos)
{

    QWidget *parent = target;
    if (parent == 0)
        parent = mainContainer();
    // You can only drop stuff onto the central widget of a QMainWindow
    // ### generalize to use container extension
    if (QMainWindow *main_win = qobject_cast<QMainWindow*>(target)) {
        if (!main_win->centralWidget()) {
            designerWarning(tr("A QMainWindow-based form does not contain a central widget."));
            return false;
        }
        const QPoint main_win_pos = main_win->mapFromGlobal(global_mouse_pos);
        const QRect central_wgt_geo = main_win->centralWidget()->geometry();
        if (!central_wgt_geo.contains(main_win_pos))
            return false;
    }

    QWidget *container = findContainer(parent, false);
    if (container == 0)
        return false;

    beginCommand(tr("Drop widget"));

    clearSelection(false);
    highlightWidget(target, target->mapFromGlobal(global_mouse_pos), FormWindow::Restore);

    QPoint offset;
    QDesignerDnDItemInterface *current = 0;
    QDesignerFormWindowCursorInterface *c = cursor();
    foreach (QDesignerDnDItemInterface *item, item_list) {
        QWidget *w = item->widget();
        if (!current)
            current = item;
        if (c->current() == w) {
            current = item;
            break;
        }
    }
    if (current) {
        QRect geom = current->decoration()->geometry();
        QPoint topLeft = container->mapFromGlobal(geom.topLeft());
        offset = designerGrid().snapPoint(topLeft) - topLeft;
    }

    foreach (QDesignerDnDItemInterface *item, item_list) {
        DomUI *dom_ui = item->domUi();
        QRect geometry = item->decoration()->geometry();
        Q_ASSERT(dom_ui != 0);

        geometry.moveTopLeft(container->mapFromGlobal(geometry.topLeft()) + offset);
        if (item->type() == QDesignerDnDItemInterface::CopyDrop) { // from widget box or CTRL + mouse move
            QWidget *widget = createWidget(dom_ui, geometry, parent);
            if (!widget) {
                endCommand();
                return false;
            }
            selectWidget(widget, true);
            mainContainer()->setFocus(Qt::MouseFocusReason); // in case focus was in e.g. object inspector
        } else { // same form move
            QWidget *widget = item->widget();
            Q_ASSERT(widget != 0);
            QDesignerFormWindowInterface *dest = findFormWindow(widget);
            if (dest == this) {
                dragWidgetWithinForm(widget, geometry, container);
            } else { // from other form
                FormWindow *source = qobject_cast<FormWindow*>(item->source());
                Q_ASSERT(source != 0);

                source->deleteWidgetList(QWidgetList() << widget);
                QWidget *new_widget = createWidget(dom_ui, geometry, parent);

                selectWidget(new_widget, true);
            }
        }
    }

    core()->formWindowManager()->setActiveFormWindow(this);
    mainContainer()->activateWindow();
    endCommand();
    return true;
}

QDir FormWindow::absoluteDir() const
{
    if (fileName().isEmpty())
        return QDir::current();

    return QFileInfo(fileName()).absoluteDir();
}

void FormWindow::layoutDefault(int *margin, int *spacing)
{
    *margin = m_defaultMargin;
    *spacing = m_defaultSpacing;
}

void FormWindow::setLayoutDefault(int margin, int spacing)
{
    m_defaultMargin = margin;
    m_defaultSpacing = spacing;
}

void FormWindow::layoutFunction(QString *margin, QString *spacing)
{
    *margin = m_marginFunction;
    *spacing = m_spacingFunction;
}

void FormWindow::setLayoutFunction(const QString &margin, const QString &spacing)
{
    m_marginFunction = margin;
    m_spacingFunction = spacing;
}

QString FormWindow::pixmapFunction() const
{
    return m_pixmapFunction;
}

void FormWindow::setPixmapFunction(const QString &pixmapFunction)
{
    m_pixmapFunction = pixmapFunction;
}

QStringList FormWindow::includeHints() const
{
    return m_includeHints;
}

void FormWindow::setIncludeHints(const QStringList &includeHints)
{
    m_includeHints = includeHints;
}

QString FormWindow::exportMacro() const
{
    return m_exportMacro;
}

void FormWindow::setExportMacro(const QString &exportMacro)
{
    m_exportMacro = exportMacro;
}

QEditorFormBuilder *FormWindow::createFormBuilder()
{
    return new QDesignerResource(this);
}

QWidget *FormWindow::formContainer() const
{
    return m_widgetStack->formContainer();
}

QUndoStack *FormWindow::commandHistory() const
{
    return const_cast<QDesignerUndoStack &>(m_undoStack).qundoStack();
}

} // namespace

QT_END_NAMESPACE

