tools/designer/src/components/formeditor/formwindow.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.
00004 **
00005 ** This file is part of the Qt Designer of the Qt Toolkit.
00006 **
00007 ** This file may be used under the terms of the GNU General Public
00008 ** License version 2.0 as published by the Free Software Foundation
00009 ** and appearing in the file LICENSE.GPL included in the packaging of
00010 ** this file.  Please review the following information to ensure GNU
00011 ** General Public Licensing requirements will be met:
00012 ** http://www.trolltech.com/products/qt/opensource.html
00013 **
00014 ** If you are unsure which license is appropriate for your use, please
00015 ** review the following information:
00016 ** http://www.trolltech.com/products/qt/licensing.html or contact the
00017 ** sales department at sales@trolltech.com.
00018 **
00019 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00020 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00021 **
00022 ****************************************************************************/
00023 
00024 /*
00025 TRANSLATOR qdesigner_internal::FormWindow
00026 */
00027 
00028 #include "formwindow.h"
00029 #include "formwindow_dnditem.h"
00030 #include "formwindow_widgetstack.h"
00031 #include "formwindowcursor.h"
00032 #include "formwindowmanager.h"
00033 #include "tool_widgeteditor.h"
00034 #include "widgetselection.h"
00035 
00036 // shared
00037 #include <qdesigner_promotedwidget_p.h>
00038 #include <qdesigner_tabwidget_p.h>
00039 #include <qdesigner_toolbox_p.h>
00040 #include <qdesigner_stackedbox_p.h>
00041 #include "qdesigner_resource.h"
00042 #include <qdesigner_command_p.h>
00043 #include <qdesigner_widget_p.h>
00044 #include <qdesigner_utils_p.h>
00045 #include <qlayout_widget_p.h>
00046 #include <spacer_widget_p.h>
00047 #include <invisible_widget_p.h>
00048 #include <layoutinfo_p.h>
00049 #include <connectionedit_p.h>
00050 #include <actionprovider_p.h>
00051 
00052 // sdk
00053 #include <QtDesigner/QtDesigner>
00054 
00055 #include <QtGui>
00056 #include <QtDebug>
00057 
00058 namespace qdesigner_internal {
00059 
00060 class FriendlyWidget: public QWidget
00061 {
00062 public:
00063     FriendlyWidget() { Q_ASSERT(0); }
00064 
00065     friend class FormWindow;
00066 };
00067 
00068 class BlockSelection
00069 {
00070 public:
00071     BlockSelection(FormWindow *fw)
00072         : m_formWindow(fw)
00073     {
00074         if (m_formWindow)
00075             m_blocked = m_formWindow->blockSelectionChanged(true);
00076     }
00077 
00078     ~BlockSelection()
00079     {
00080         if (m_formWindow)
00081             m_formWindow->blockSelectionChanged(m_blocked);
00082     }
00083 
00084 private:
00085     QPointer<FormWindow> m_formWindow;
00086     bool m_blocked;
00087 };
00088 
00089 FormWindow::FormWindow(FormEditor *core, QWidget *parent, Qt::WindowFlags flags)
00090     : QDesignerFormWindowInterface(parent, flags),
00091       m_core(core), m_widgetStack(0)
00092 {
00093     init();
00094 
00095     m_cursor = new FormWindowCursor(this, this);
00096 
00097     core->formWindowManager()->addFormWindow(this);
00098 
00099     setDirty(false);
00100 }
00101 
00102 FormWindow::~FormWindow()
00103 {
00104     Q_ASSERT(core() != 0);
00105     Q_ASSERT(core()->metaDataBase() != 0);
00106     Q_ASSERT(core()->formWindowManager() != 0);
00107 
00108     core()->formWindowManager()->removeFormWindow(this);
00109     core()->metaDataBase()->remove(this);
00110 
00111     QList<QWidget*> l = widgets();
00112     foreach (QWidget *w, l)
00113         core()->metaDataBase()->remove(w);
00114 
00115     m_widgetStack = 0;
00116     m_rubberBand = 0;
00117 
00118     qDeleteAll(selections);
00119 }
00120 
00121 QDesignerFormEditorInterface *FormWindow::core() const
00122 {
00123     return m_core;
00124 }
00125 
00126 QDesignerFormWindowCursorInterface *FormWindow::cursor() const
00127 {
00128     return m_cursor;
00129 }
00130 
00131 bool FormWindow::hasFeature(Feature f) const
00132 {
00133     return f & m_feature;
00134 }
00135 
00136 void FormWindow::updateWidgets()
00137 {
00138     if (!m_mainContainer)
00139         return;
00140 }
00141 
00142 int FormWindow::widgetDepth(QWidget *w)
00143 {
00144     int d = -1;
00145     while (w && !w->isWindow()) {
00146         d++;
00147         w = w->parentWidget();
00148     }
00149 
00150     return d;
00151 }
00152 
00153 bool FormWindow::isChildOf(QWidget *c, const QWidget *p)
00154 {
00155     while (c /*&& !c->isWindow()*/) {
00156         if (c == p)
00157             return true;
00158         c = c->parentWidget();
00159     }
00160     return false;
00161 }
00162 
00163 FormWindow::Feature FormWindow::features() const
00164 {
00165     return m_feature;
00166 }
00167 
00168 static void recursiveUpdate(QWidget *w)
00169 {
00170     w->update();
00171 
00172     const QObjectList &l = w->children();
00173     QObjectList::const_iterator it = l.begin();
00174     for (; it != l.end(); ++it) {
00175         if (QWidget *w = qobject_cast<QWidget*>(*it))
00176             recursiveUpdate(w);
00177     }
00178 }
00179 
00180 void FormWindow::setFeatures(Feature f)
00181 {
00182     m_feature = f;
00183     emit featureChanged(f);
00184     recursiveUpdate(this);
00185 }
00186 
00187 void FormWindow::setCursorToAll(const QCursor &c, QWidget *start)
00188 {
00189     start->setCursor(c);
00190     QList<QWidget*> widgets = qFindChildren<QWidget*>(start);
00191     foreach (QWidget *widget, widgets) {
00192         if (!qobject_cast<WidgetHandle*>(widget)) {
00193             widget->setCursor(c);
00194         }
00195     }
00196 }
00197 
00198 void FormWindow::init()
00199 {
00200     if (FormWindowManager *manager = qobject_cast<FormWindowManager*> (core()->formWindowManager())) {
00201         m_commandHistory = new QUndoStack(this);
00202         manager->undoGroup()->addStack(m_commandHistory);
00203     }
00204 
00205     m_blockSelectionChanged = false;
00206 
00207     m_defaultMargin = INT_MIN;
00208     m_defaultSpacing = INT_MIN;
00209 
00210     QHBoxLayout *layout = new QHBoxLayout(this);
00211     layout->setMargin(0);
00212 
00213     m_widgetStack = new FormWindowWidgetStack(this);
00214     connect(m_widgetStack, SIGNAL(currentToolChanged(int)), this, SIGNAL(toolChanged(int)));
00215     layout->addWidget(m_widgetStack);
00216 
00217     m_feature = DefaultFeature;
00218 
00219     m_selectionChangedTimer = new QTimer(this);
00220     m_selectionChangedTimer->setSingleShot(true);
00221     connect(m_selectionChangedTimer, SIGNAL(timeout()), this, SLOT(selectionChangedTimerDone()));
00222 
00223     m_checkSelectionTimer = new QTimer(this);
00224     m_checkSelectionTimer->setSingleShot(true);
00225     connect(m_checkSelectionTimer, SIGNAL(timeout()), this, SLOT(checkSelectionNow()));
00226 
00227     m_geometryChangedTimer = new QTimer(this);
00228     m_geometryChangedTimer->setSingleShot(true);
00229     connect(m_geometryChangedTimer, SIGNAL(timeout()), this, SIGNAL(geometryChanged()));
00230 
00231     m_rubberBand = 0;
00232 
00233     setGrid(QPoint(10,10));
00234 
00235     setFocusPolicy(Qt::StrongFocus);
00236 
00237     m_mainContainer = 0;
00238     m_currentWidget = 0;
00239     oldRectValid = false;
00240     drawRubber = false;
00241 
00242     targetContainer = 0;
00243     hadOwnPalette = false;
00244     startWidget = 0;
00245     endWidget = 0;
00246 
00247     connect(m_commandHistory, SIGNAL(indexChanged(int)), this, SLOT(updateDirty()));
00248     connect(m_commandHistory, SIGNAL(indexChanged(int)), this, SIGNAL(changed()));
00249     connect(m_commandHistory, SIGNAL(indexChanged(int)), this, SLOT(checkSelection()));
00250 
00251     core()->metaDataBase()->add(this);
00252 
00253     initializeCoreTools();
00254 
00255     QAction *a = new QAction(this);
00256     a->setText(tr("Edit contents"));
00257     a->setShortcut(tr("F2"));
00258     connect(a, SIGNAL(triggered()), this, SLOT(editContents()));
00259     addAction(a);
00260 }
00261 
00262 QWidget *FormWindow::mainContainer() const
00263 {
00264     return m_mainContainer;
00265 }
00266 
00267 void FormWindow::setMainContainer(QWidget *w)
00268 {
00269     if (w == m_mainContainer) {
00270         // nothing to do
00271         return;
00272     }
00273 
00274     if (m_mainContainer) {
00275         unmanageWidget(m_mainContainer);
00276         delete m_mainContainer;
00277         m_mainContainer = 0;
00278     }
00279 
00280     m_mainContainer = w;
00281     w->setAutoFillBackground(true);
00282     QSize sz = m_mainContainer->size();
00283 
00284     m_mainContainer->setParent(m_widgetStack, 0);
00285     m_mainContainer->raise();
00286     m_mainContainer->show();
00287 
00288     m_widgetStack->setCurrentTool(m_widgetEditor);
00289 
00290     setCurrentWidget(m_mainContainer);
00291 
00292     manageWidget(m_mainContainer);
00293 
00294     if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), m_mainContainer)) {
00295         sheet->setVisible(sheet->indexOf(QLatin1String("windowTitle")), true);
00296         sheet->setVisible(sheet->indexOf(QLatin1String("windowIcon")), true);
00297         // ### generalize
00298     }
00299 
00300     m_mainContainer->setFocusPolicy(Qt::StrongFocus);
00301     m_mainContainer->resize(sz);
00302 
00303     emit mainContainerChanged(m_mainContainer);
00304 }
00305 
00306 QWidget *FormWindow::findTargetContainer(QWidget *widget) const
00307 {
00308     Q_ASSERT(widget);
00309 
00310     while (QWidget *parentWidget = widget->parentWidget()) {
00311         if (LayoutInfo::layoutType(m_core, parentWidget) == LayoutInfo::NoLayout && isManaged(widget))
00312             return widget;
00313 
00314         widget = parentWidget;
00315     }
00316 
00317     return mainContainer();
00318 }
00319 
00320 bool FormWindow::handleMousePressEvent(QWidget * /*widget*/, QWidget *managedWidget, QMouseEvent *e)
00321 {
00322     startPos = QPoint();
00323     e->accept();
00324 
00325     BlockSelection blocker(this);
00326 
00327     if (core()->formWindowManager()->activeFormWindow() != this)
00328         core()->formWindowManager()->setActiveFormWindow(this);
00329 
00330     if (e->buttons() != Qt::LeftButton)
00331         return true;
00332 
00333     startPos = mapFromGlobal(e->globalPos());
00334 
00335     bool inLayout = LayoutInfo::isWidgetLaidout(m_core, managedWidget);
00336 
00337     // if the dragged widget is not in a layout, raise it
00338     if (inLayout == false)
00339         managedWidget->raise();
00340 
00341     if (isMainContainer(managedWidget) == true) { // press was on the formwindow
00342         clearSelection(false);
00343 
00344         drawRubber = true;
00345         currRect = QRect();
00346         startRectDraw(mapFromGlobal(e->globalPos()), this, Rubber);
00347         return true;
00348     }
00349 
00350     bool selected = isWidgetSelected(managedWidget);
00351 
00352     if (e->modifiers() & Qt::ShiftModifier) {
00353         // shift-click - toggle selection state of widget
00354         selectWidget(managedWidget, !selected);
00355         return true;
00356     }
00357 
00358     QWidget *current = managedWidget;
00359 
00360     if (!selected)
00361         clearSelection(false);
00362 
00363     bool curLaidOut = false;
00364     bool curSelected = false;
00365     for (;;) {
00366         curLaidOut = current ? LayoutInfo::isWidgetLaidout(core(), current) : false;
00367         curSelected = current ? isWidgetSelected(current) : false;
00368 
00369         if (!current || !curLaidOut || !curSelected)
00370             break;
00371 
00372         current = designerWidget(current->parentWidget());
00373     }
00374 
00375     if (!(current == 0 || !curLaidOut && curSelected)) {
00376         selectWidget(current);
00377         raiseChildSelections(current);
00378     }
00379 
00380     return true;
00381 }
00382 
00383 bool FormWindow::isPageOfContainerWidget(QWidget *widget) const
00384 {
00385     QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(),
00386                 widget->parentWidget());
00387 
00388     if (c != 0) {
00389         for (int i = 0; i<c->count(); ++i) {
00390             if (widget == c->widget(i))
00391                 return true;
00392         }
00393     }
00394 
00395     return false;
00396 }
00397 
00398 bool FormWindow::handleMouseMoveEvent(QWidget *, QWidget *, QMouseEvent *e)
00399 {
00400     e->accept();
00401 
00402     if (e->buttons() != Qt::LeftButton || startPos.isNull())
00403         return true;
00404 
00405     QPoint pos = mapFromGlobal(e->globalPos());
00406 
00407     if (drawRubber == true) {
00408         continueRectDraw(pos, this, Rubber);
00409         return true;
00410     }
00411 
00412     bool canStartDrag = (startPos - pos).manhattanLength() > QApplication::startDragDistance();
00413 
00414     if (canStartDrag == false) {
00415         // nothing to do
00416         return true;
00417     }
00418 
00419     bool blocked = blockSelectionChanged(true);
00420 
00421     QList<QWidget*> sel = selectedWidgets();
00422     simplifySelection(&sel);
00423 
00424     QSet<QWidget*> widget_set;
00425 
00426     foreach (QWidget *child, sel) {
00427         QWidget *current = child;
00428 
00429         bool done = false;
00430         while (!isMainContainer(current) && !done) {
00431             QDesignerContainerExtension *c = 0;
00432             c = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), current->parentWidget());
00433 
00434             if (!isManaged(current)) {
00435                 current = current->parentWidget();
00436                 continue;
00437             } else if (LayoutInfo::isWidgetLaidout(core(), current)) {
00438                 current = current->parentWidget();
00439                 continue;
00440             } else if (isPageOfContainerWidget(current)) {
00441                 current = current->parentWidget();
00442                 continue;
00443             } else if (current->parentWidget()) {
00444                 QScrollArea *area = qobject_cast<QScrollArea*>(current->parentWidget()->parentWidget());
00445                 if (area && area->widget() == current) {
00446                     current = area;
00447                     continue;
00448                 }
00449             }
00450 
00451             done = true;
00452         }
00453 
00454         if (current == mainContainer())
00455             continue;
00456 
00457         widget_set.insert(current);
00458     }
00459 
00460     sel = widget_set.toList();
00461 
00462     QDesignerResource builder(this);
00463 
00464     QList<QDesignerDnDItemInterface*> item_list;
00465     foreach (QWidget *widget, sel) {
00466         if (e->modifiers()
00467 #ifndef Q_WS_MAC
00468         & Qt::ControlModifier
00469 #else
00470         & Qt::AltModifier
00471 #endif
00472         ) {
00473             item_list.append(new FormWindowDnDItem(QDesignerDnDItemInterface::CopyDrop,
00474                 this, widget, mapToGlobal(startPos)));
00475         } else {
00476             item_list.append(new FormWindowDnDItem(QDesignerDnDItemInterface::MoveDrop,
00477                 this, widget, mapToGlobal(startPos)));
00478             widget->hide();
00479         }
00480     }
00481 
00482     blockSelectionChanged(blocked);
00483 
00484     if (sel.count())
00485         core()->formWindowManager()->dragItems(item_list);
00486 
00487     startPos = QPoint();
00488 
00489     return true;
00490 }
00491 
00492 bool FormWindow::handleMouseReleaseEvent(QWidget *, QWidget *, QMouseEvent *e)
00493 {
00494     e->accept();
00495 
00496     if (drawRubber) { // we were drawing a rubber selection
00497         endRectDraw(); // get rid of the rectangle
00498 
00499         bool blocked = blockSelectionChanged(true);
00500         selectWidgets(); // select widgets which intersect the rect
00501         blockSelectionChanged(blocked);
00502 
00503         drawRubber = false;
00504     }
00505 
00506     startPos = QPoint();
00507 
00508     emitSelectionChanged(); // inform about selection changes
00509 
00510     return true;
00511 }
00512 
00513 void FormWindow::checkPreviewGeometry(QRect &r)
00514 {
00515     if (!rect().contains(r)) {
00516         if (r.left() < rect().left())
00517             r.moveTopLeft(QPoint(0, r.top()));
00518         if (r.right() > rect().right())
00519             r.moveBottomRight(QPoint(rect().right(), r.bottom()));
00520         if (r.top() < rect().top())
00521             r.moveTopLeft(QPoint(r.left(), rect().top()));
00522         if (r.bottom() > rect().bottom())
00523             r.moveBottomRight(QPoint(r.right(), rect().bottom()));
00524     }
00525 }
00526 
00527 void FormWindow::startRectDraw(const QPoint &pos, QWidget *, RectType t)
00528 {
00529     oldRectValid = false;
00530 
00531     rectAnchor = (t == Insert) ? gridPoint(pos) : pos;
00532 
00533     currRect = QRect(rectAnchor, QSize(0, 0));
00534     if (!m_rubberBand)
00535         m_rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
00536     m_rubberBand->setGeometry(currRect);
00537     m_rubberBand->show();
00538 }
00539 
00540 void FormWindow::continueRectDraw(const QPoint &pos, QWidget *, RectType t)
00541 {
00542     QPoint p2 = (t == Insert) ? gridPoint(pos) : pos;
00543 
00544     QRect r(rectAnchor, p2);
00545     r = r.normalized();
00546 
00547     if (currRect == r)
00548         return;
00549 
00550     if (r.width() > 1 || r.height() > 1) {
00551         oldRectValid = true;
00552         currRect = r;
00553         if (m_rubberBand)
00554             m_rubberBand->setGeometry(currRect);
00555     } else {
00556         oldRectValid = false;
00557     }
00558 }
00559 
00560 void FormWindow::endRectDraw()
00561 {
00562     if (m_rubberBand) {
00563         delete m_rubberBand;
00564         m_rubberBand = 0;
00565     }
00566 }
00567 
00568 QPoint FormWindow::gridPoint(const QPoint &p) const
00569 {
00570     return QPoint(((p.x() + grid().x()/2) / grid().x()) * grid().x(),
00571                    ((p.y() + grid().y()/2) / grid().y()) * grid().y());
00572 }
00573 
00574 QWidget *FormWindow::currentWidget() const
00575 {
00576     return m_currentWidget;
00577 }
00578 
00579 void FormWindow::setCurrentWidget(QWidget *currentWidget)
00580 {
00581     m_currentWidget = currentWidget;
00582 }
00583 
00584 QSize FormWindow::sizeHint() const
00585 {
00586     QMainWindow *mw = qobject_cast<QMainWindow*>(mainContainer());
00587     if (!mw) {
00588         return QSize(400, 300);
00589     }
00590     QSize sh = mw->sizeHint();
00591     if (sh.width() < 400)
00592         sh.setWidth(400);
00593     if (sh.height() < 300)
00594         sh.setHeight(300);
00595     return sh;
00596 
00597 }
00598 
00599 void FormWindow::selectWidget(QWidget* w, bool select)
00600 {
00601     if (!isManaged(w) && !isCentralWidget(w))
00602         return;
00603 
00604     if (!select && !isWidgetSelected(w))
00605         return;
00606 
00607     if (!mainContainer())
00608         return;
00609 
00610     if (isMainContainer(w)) {
00611         QWidget *opw = m_currentWidget;
00612         setCurrentWidget(mainContainer());
00613         repaintSelection(opw);
00614         emitSelectionChanged();
00615         return;
00616     }
00617 
00618     if (isCentralWidget(w)) {
00619         QWidget *opw = m_currentWidget;
00620         setCurrentWidget(mainContainer());
00621         repaintSelection(opw);
00622         emitSelectionChanged();
00623         return;
00624     }
00625 
00626     if (select) {
00627         QWidget *opw = m_currentWidget;
00628         setCurrentWidget(w);
00629         repaintSelection(opw);
00630         WidgetSelection *s = usedSelections.value(w);
00631         if (s != 0) {
00632             s->show();
00633             return;
00634         }
00635 
00636         QListIterator<WidgetSelection*> it(selections);
00637         while (it.hasNext()) {
00638             WidgetSelection *sel = it.next();
00639             if (!sel->isUsed()) {
00640                 s = sel;
00641                 break;
00642             }
00643         }
00644 
00645         if (s == 0) {
00646             s = new WidgetSelection(this, &usedSelections);
00647             selections.append(s);
00648         }
00649 
00650         s->setWidget(w);
00651     } else {
00652         if (WidgetSelection *s = usedSelections.value(w))
00653             s->setWidget(0);
00654 
00655         if (!usedSelections.isEmpty())
00656             setCurrentWidget((*usedSelections.begin())->widget());
00657         else
00658             setCurrentWidget(mainContainer());
00659 
00660         repaintSelection(currentWidget());
00661     }
00662 
00663     emitSelectionChanged();
00664 }
00665 
00666 void FormWindow::hideSelection(QWidget *w)
00667 {
00668     selectWidget(w, false);
00669 }
00670 
00671 void FormWindow::clearSelection(bool changePropertyDisplay)
00672 {
00673     for (QHash<QWidget *, WidgetSelection *>::Iterator it = usedSelections.begin(); it != usedSelections.end(); ++it) {
00674         it.value()->setWidget(0, false);
00675     }
00676 
00677     usedSelections.clear();
00678 
00679     if (changePropertyDisplay == false)
00680         return;
00681 
00682     setCurrentWidget(mainContainer());
00683 
00684     if (m_currentWidget)
00685         repaintSelection(m_currentWidget);
00686 
00687     emitSelectionChanged();
00688 }
00689 
00690 void FormWindow::emitSelectionChanged()
00691 {
00692     if (m_blockSelectionChanged == true) {
00693         // nothing to do
00694         return;
00695     }
00696 
00697     m_selectionChangedTimer->start(0);
00698 }
00699 
00700 void FormWindow::selectionChangedTimerDone()
00701 {
00702     emit selectionChanged();
00703 }
00704 
00705 void FormWindow::repaintSelection(QWidget *w)
00706 {
00707     if (WidgetSelection *s = usedSelections.value(w))
00708         s->update();
00709 }
00710 
00711 bool FormWindow::isWidgetSelected(QWidget *w) const
00712 {
00713     return usedSelections.contains(w);
00714 }
00715 
00716 bool FormWindow::isMainContainer(const QWidget *w) const
00717 {
00718     return w && (w == this || w == mainContainer());
00719 }
00720 
00721 void FormWindow::updateChildSelections(QWidget *w)
00722 {
00723     QList<QWidget*> l = qFindChildren<QWidget*>(w);
00724 
00725     QListIterator<QWidget*> it(l);
00726     while (it.hasNext()) {
00727         QWidget *w = it.next();
00728         if (isManaged(w)) {
00729             updateSelection(w);
00730         }
00731     }
00732 }
00733 
00734 void FormWindow::updateSelection(QWidget *w)
00735 {
00736     WidgetSelection *s = usedSelections.value(w);
00737     if (!w->isVisibleTo(this)) {
00738         selectWidget(w, false);
00739     } else if (s)
00740         s->updateGeometry();
00741 }
00742 
00743 QWidget *FormWindow::designerWidget(QWidget *w) const
00744 {
00745     while (w && !isMainContainer(w) && !isManaged(w) || isCentralWidget(w))
00746         w = w->parentWidget();
00747 
00748     return w;
00749 }
00750 
00751 bool FormWindow::isCentralWidget(QWidget *w) const
00752 {
00753     if (QMainWindow *mainWindow = qobject_cast<QMainWindow*>(mainContainer()))
00754         return w == mainWindow->centralWidget();
00755 
00756     return false;
00757 }
00758 
00759 void FormWindow::ensureUniqueObjectName(QObject *object)
00760 {
00761     QString name = object->objectName();
00762 
00763     if (!unify(object, name, true)) {
00764         object->setObjectName(name);
00765     }
00766 }
00767 
00768 template <class T, class P>
00769 void merge(QList<T> *target, const QList<P> &source)
00770 {
00771     foreach (P item, source) {
00772         target->append(item);
00773     }
00774 }
00775 
00776 bool FormWindow::unify(QObject *w, QString &s, bool changeIt)
00777 {
00778     bool found = !isMainContainer(static_cast<QWidget*>(w)) && objectName() == s;
00779 
00780     if (!found) {
00781         QList<QObject*> objects;
00782 
00783         if (mainContainer()) {
00784             objects.append(mainContainer());
00785             merge(&objects, qFindChildren<QWidget*>(mainContainer()));
00786             merge(&objects, qFindChildren<QAction*>(mainContainer()));
00787         }
00788 
00789         QMutableListIterator<QObject*> mit(objects);
00790         while (mit.hasNext()) {
00791             if (!core()->metaDataBase()->item(mit.next())) {
00792                 mit.remove();
00793             }
00794         }
00795 
00796         QListIterator<QObject*> it(objects);
00797         while (it.hasNext()) {
00798             QObject *child = it.next();
00799 
00800             if (child != w && child->objectName() == s) {
00801                 found = true;
00802 
00803                 if (!changeIt)
00804                     break;
00805 
00806                 qlonglong num = 0;
00807                 qlonglong factor = 1;
00808                 int idx = s.length()-1;
00809                 for ( ; (idx > 0) && s.at(idx).isDigit(); --idx) {
00810                     num += (s.at(idx).unicode() - QLatin1Char('0').unicode()) * factor;
00811                     factor *= 10;
00812                 }
00813 
00814                 if ((idx >= 0) && (QLatin1Char('_') == s.at(idx)))
00815                     s = s.left(idx+1) + QString::number(num+1);
00816                 else
00817                     s = s + QLatin1String("_2");
00818 
00819                 it.toFront();
00820             }
00821         }
00822     }
00823 
00824     return !found;
00825 }
00826 
00827 /* already_in_form is true when we are moving a widget from one parent to another inside the same
00828    form. All this means is that InsertWidgetCommand::undo() must not unmanage it. */
00829 
00830 void FormWindow::insertWidget(QWidget *w, const QRect &rect, QWidget *container, bool already_in_form)
00831 {
00832     clearSelection(false);
00833 
00834     beginCommand(tr("Insert widget '%1").arg(QString::fromUtf8(w->metaObject()->className()))); // ### use the WidgetDatabaseItem
00835 
00836     /* Reparenting into a QSplitter automatically adjusts child's geometry. We create the geometry
00837        command before we push the reparent command, so that the geometry command has the original
00838        geometry of the widget. */
00839     QRect r = rect;
00840     Q_ASSERT(r.isValid());
00841     r.moveTopLeft(gridPoint(container->mapFromGlobal(r.topLeft())));
00842     SetPropertyCommand *geom_cmd = new SetPropertyCommand(this);
00843     geom_cmd->init(w, QLatin1String("geometry"), r); // ### use rc.size()
00844 
00845     if (w->parentWidget() != container) {
00846         ReparentWidgetCommand *cmd = new ReparentWidgetCommand(this);
00847         cmd->init(w, container);
00848         m_commandHistory->push(cmd);
00849     }
00850 
00851     m_commandHistory->push(geom_cmd);
00852 
00853     InsertWidgetCommand *cmd = new InsertWidgetCommand(this);
00854     cmd->init(w, already_in_form);
00855     m_commandHistory->push(cmd);
00856 
00857     endCommand();
00858 
00859     w->show();
00860 }
00861 
00862 QWidget *FormWindow::createWidget(DomUI *ui, const QRect &rc, QWidget *target)
00863 {
00864     QWidget *container = findContainer(target, false);
00865     if (!container)
00866         return 0;
00867 
00868     if (isMainContainer(container)) {
00869         if (QMainWindow *mw = qobject_cast<QMainWindow*>(container)) {
00870             Q_ASSERT(mw->centralWidget() != 0);
00871             container = mw->centralWidget();
00872         }
00873     }
00874 
00875     QDesignerResource resource(this);
00876     QList<QWidget*> widgets = resource.paste(ui, container);
00877     Q_ASSERT(widgets.size() == 1); // multiple-paste from DomUI not supported yet
00878 
00879     insertWidget(widgets.first(), rc, container);
00880     return widgets.first();
00881 }
00882 
00883 static bool isDescendant(const QWidget *parent, const QWidget *child)
00884 {
00885     for (; child != 0; child = child->parentWidget()) {
00886         if (child == parent)
00887             return true;
00888     }
00889     return false;
00890 }
00891 
00892 void FormWindow::resizeWidget(QWidget *widget, const QRect &geometry)
00893 {
00894     Q_ASSERT(isDescendant(this, widget));
00895 
00896     QRect r = geometry;
00897     r.moveTopLeft(gridPoint(geometry.topLeft()));
00898     SetPropertyCommand *cmd = new SetPropertyCommand(this);
00899     cmd->init(widget, QLatin1String("geometry"), r);
00900     cmd->setText(tr("Resize"));
00901     m_commandHistory->push(cmd);
00902 }
00903 
00904 void FormWindow::raiseChildSelections(QWidget *w)
00905 {
00906     QList<QWidget*> l = qFindChildren<QWidget*>(w);
00907     if (l.isEmpty())
00908         return;
00909 
00910     QHashIterator<QWidget *, WidgetSelection *> it(usedSelections);
00911     while (it.hasNext()) {
00912         it.next();
00913 
00914         WidgetSelection *w = it.value();
00915         if (l.contains(w->widget()))
00916             w->show();
00917     }
00918 }
00919 
00920 QWidget *FormWindow::containerAt(const QPoint &pos, QWidget *notParentOf)
00921 {
00922     QWidget *container = 0;
00923     int depth = -1;
00924     QList<QWidget*> selected = selectedWidgets();
00925     if (rect().contains(mapFromGlobal(pos))) {
00926         container = mainContainer();
00927         depth = widgetDepth(container);
00928     }
00929 
00930     QListIterator<QWidget*> it(m_widgets);
00931     while (it.hasNext()) {
00932         QWidget *wit = it.next();
00933         if (qobject_cast<QLayoutWidget*>(wit) || qobject_cast<QSplitter*>(wit))
00934             continue;
00935         if (!wit->isVisibleTo(this))
00936             continue;
00937         if (selected.indexOf(wit) != -1)
00938             continue;
00939         if (!core()->widgetDataBase()->isContainer(wit) &&
00940              wit != mainContainer())
00941             continue;
00942 
00943         // the rectangles of all ancestors of the container must contain the insert position
00944         QWidget *w = wit;
00945         while (w && !w->isWindow()) {
00946             if (!w->rect().contains((w->mapFromGlobal(pos))))
00947                 break;
00948             w = w->parentWidget();
00949         }
00950         if (!(w == 0 || w->isWindow()))
00951             continue; // we did not get through the full while loop
00952 
00953         int wd = widgetDepth(wit);
00954         if (wd == depth && container) {
00955             if (wit->parentWidget()->children().indexOf(wit) >
00956                  container->parentWidget()->children().indexOf(container))
00957                 wd++;
00958         }
00959         if (wd > depth && !isChildOf(wit, notParentOf)) {
00960             depth = wd;
00961             container = wit;
00962         }
00963     }
00964     return container;
00965 }
00966 
00967 QList<QWidget*> FormWindow::selectedWidgets() const
00968 {
00969     return usedSelections.keys();
00970 }
00971 
00972 void FormWindow::raiseSelection(QWidget *w)
00973 {
00974     WidgetSelection *s = usedSelections.value(w);
00975     if (s)
00976         s->show();
00977 }
00978 
00979 void FormWindow::selectWidgets()
00980 {
00981     QList<QWidget*> l = qFindChildren<QWidget*>(mainContainer());
00982     QListIterator <QWidget*> it(l);
00983     const QRect selRect(mapToGlobal(currRect.topLeft()), currRect.size());
00984     while (it.hasNext()) {
00985         QWidget *w = it.next();
00986         if (w->isVisibleTo(this) && isManaged(w)) {
00987             QPoint p = w->mapToGlobal(QPoint(0,0));
00988             QRect r(p, w->size());
00989             if (r.intersects(selRect) && !r.contains(selRect))
00990                 selectWidget(w);
00991         }
00992     }
00993 
00994     emitSelectionChanged();
00995 }
00996 
00997 bool FormWindow::handleKeyPressEvent(QWidget *widget, QWidget *, QKeyEvent *e)
00998 {
00999     if (qobject_cast<FormWindow*>(widget) || qobject_cast<QMenu*>(widget))
01000         return false;
01001 
01002     e->accept(); // we always accept!
01003 
01004     switch (e->key()) {
01005         default: break; // we don't care about the other keys
01006 
01007         case Qt::Key_Delete:
01008         case Qt::Key_Backspace:
01009             deleteWidgets();
01010             break;
01011 
01012         case Qt::Key_Tab:
01013             cursor()->movePosition(QDesignerFormWindowCursorInterface::Next);
01014             break;
01015 
01016         case Qt::Key_Backtab:
01017             cursor()->movePosition(QDesignerFormWindowCursorInterface::Prev);
01018             break;
01019 
01020         case Qt::Key_Left:
01021         case Qt::Key_Right:
01022         case Qt::Key_Up:
01023         case Qt::Key_Down:
01024             if (e->modifiers() & Qt::ControlModifier)
01025                 handleArrowKeyEvent(e->key(), e->modifiers() == Qt::ControlModifier);
01026             break;
01027     }
01028 
01029     return true;
01030 }
01031 
01032 void FormWindow::handleArrowKeyEvent(int key, bool modifier)
01033 {
01034     bool startMacro = false;
01035     QDesignerFormWindowCursorInterface *c = cursor();
01036     if (!c->hasSelection())
01037         return;
01038 
01039     int selCount = c->selectedWidgetCount();
01040     int x = grid().x();
01041     int y = grid().y();
01042 
01043     if (modifier) {
01044         x = 1;
01045         y = 1;
01046     }
01047 
01048     // check if a layed out widget is selected
01049     for (int index=0; index<c->selectedWidgetCount(); ++index) {
01050         QWidget *w = c->selectedWidget(index);
01051         if (LayoutInfo::isWidgetLaidout(m_core, w))
01052             return;
01053     }
01054 
01055     // check if selection is the same as last time
01056     if (selCount != m_moveSelection.count() ||
01057         m_lastUndoIndex != m_commandHistory->index()) {
01058         m_moveSelection.clear();
01059         startMacro = true;
01060     } else {
01061         for (int index=0; index<selCount; ++index) {
01062             if (m_moveSelection[index]->object() != c->selectedWidget(index)) {
01063                 m_moveSelection.clear();
01064                 startMacro = true;
01065                 break;
01066             }
01067         }
01068     }
01069 
01070     if (startMacro)
01071         beginCommand(tr("Key Move"));
01072 
01073     for (int index=0; index<selCount; ++index) {
01074         QRect geom = c->selectedWidget(index)->geometry();
01075         switch(key) {
01076             case Qt::Key_Left:
01077                 geom.adjust(-x, 0,-x, 0);
01078                 break;
01079             case Qt::Key_Right:
01080                 geom.adjust( x, 0, x, 0);
01081                 break;
01082             case Qt::Key_Up:
01083                 geom.adjust( 0,-y, 0,-y);
01084                 break;
01085             case Qt::Key_Down:
01086                 geom.adjust( 0, y, 0, y);
01087                 break;
01088         }
01089 
01090         if (!modifier)
01091             geom.moveTopLeft(gridPoint(geom.topLeft()));
01092 
01093         SetPropertyCommand *cmd = 0;
01094 
01095         if (m_moveSelection.count() > index)
01096             cmd = m_moveSelection[index];
01097 
01098         if (!cmd) {
01099             cmd = new SetPropertyCommand(this);
01100             cmd->init(c->selectedWidget(index), QLatin1String("geometry"), geom);
01101             cmd->setText(tr("Key Move"));
01102             m_commandHistory->push(cmd);
01103 
01104             if (m_moveSelection.count() > index)
01105                 m_moveSelection.replace(index, cmd);
01106             else
01107                 m_moveSelection.append(cmd);
01108         } else {
01109             cmd->setNewValue(geom);
01110             cmd->redo();
01111         }
01112     }
01113 
01114     if (startMacro) {
01115         endCommand();
01116         m_lastUndoIndex = m_commandHistory->index();
01117     }
01118 }
01119 
01120 bool FormWindow::handleKeyReleaseEvent(QWidget *, QWidget *, QKeyEvent *e)
01121 {
01122     e->accept();
01123     return true;
01124 }
01125 
01126 void FormWindow::selectAll()
01127 {
01128     bool blocked = blockSignals(true);
01129     foreach (QWidget *widget, m_widgets) {
01130         if (widget->isVisibleTo(this))
01131             selectWidget(widget);
01132     }
01133 
01134     blockSignals(blocked);
01135     emitSelectionChanged();
01136 }
01137 
01138 void FormWindow::layoutHorizontal()
01139 {
01140     LayoutCommand *cmd = new LayoutCommand(this);
01141     cmd->init(mainContainer(), selectedWidgets(), LayoutInfo::HBox);
01142     clearSelection(false);
01143     commandHistory()->push(cmd);
01144 }
01145 
01146 void FormWindow::layoutVertical()
01147 {
01148     LayoutCommand *cmd = new LayoutCommand(this);
01149     cmd->init(mainContainer(), selectedWidgets(), LayoutInfo::VBox);
01150     clearSelection(false);
01151     commandHistory()->push(cmd);
01152 }
01153 
01154 void FormWindow::layoutGrid()
01155 {
01156     LayoutCommand *cmd = new LayoutCommand(this);
01157     cmd->init(mainContainer(), selectedWidgets(), LayoutInfo::Grid);
01158     clearSelection(false);
01159     commandHistory()->push(cmd);
01160 }
01161 
01162 void FormWindow::deleteWidgets(const QList<QWidget*> &widget_list)
01163 {
01164     if (widget_list.isEmpty())
01165         return;
01166 
01167     beginCommand(tr("Delete"));
01168 
01169     foreach (QWidget *w, widget_list) {
01170         emit widgetRemoved(w);
01171         DeleteWidgetCommand *cmd = new DeleteWidgetCommand(this);
01172         cmd->init(w);
01173         m_commandHistory->push(cmd);
01174     }
01175 
01176     endCommand();
01177 }
01178 
01179 
01180 void FormWindow::deleteWidgets()
01181 {
01182     QList<QWidget*> selection = selectedWidgets();
01183     simplifySelection(&selection);
01184 
01185     deleteWidgets(selection);
01186 }
01187 
01188 QString FormWindow::fileName() const
01189 {
01190     return m_fileName;
01191 }
01192 
01193 void FormWindow::setFileName(const QString &fileName)
01194 {
01195     if (m_fileName == fileName)
01196         return;
01197 
01198     m_fileName = fileName;
01199     emit fileNameChanged(fileName);
01200 }
01201 
01202 QString FormWindow::contents() const
01203 {
01204     QBuffer b;
01205     if (!b.open(QIODevice::WriteOnly))
01206         return QString();
01207 
01208     QDesignerResource resource(const_cast<FormWindow*>(this));
01209     resource.save(&b, mainContainer());
01210 
01211     return QString::fromUtf8(b.buffer());
01212 }
01213 
01214 void FormWindow::copy()
01215 {
01216     QBuffer b;
01217     if (!b.open(QIODevice::WriteOnly))
01218         return;
01219 
01220     QDesignerResource resource(this);
01221     QList<QWidget*> sel = selectedWidgets();
01222     simplifySelection(&sel);
01223     resource.copy(&b, sel);
01224 
01225     qApp->clipboard()->setText(QString::fromUtf8(b.buffer()), QClipboard::Clipboard);
01226 }
01227 
01228 void FormWindow::cut()
01229 {
01230     copy();
01231     deleteWidgets();
01232 }
01233 
01234 void FormWindow::paste()
01235 {
01236     QWidget *w = mainContainer();
01237     QList<QWidget*> l(selectedWidgets());
01238     if (l.count() == 1) {
01239         w = l.first();
01240         w = m_core->widgetFactory()->containerOfWidget(w);
01241         if (LayoutInfo::layoutType(m_core, w) != LayoutInfo::NoLayout ||
01242              (!core()->widgetDataBase()->isContainer(w) &&
01243                w != mainContainer()))
01244             w = mainContainer();
01245     }
01246 
01247     if (w && LayoutInfo::layoutType(m_core, w) == LayoutInfo::NoLayout) {
01248         clearSelection(true);
01249 
01250         QByteArray code = qApp->clipboard()->text().toUtf8();
01251         QBuffer b(&code);
01252         b.open(QIODevice::ReadOnly);
01253 
01254         QDesignerResource resource(this);
01255         QWidget *widget = core()->widgetFactory()->containerOfWidget(w);
01256         QList<QWidget*> widgets = resource.paste(&b, widget);
01257 
01258         beginCommand(tr("Paste"));
01259         foreach (QWidget *w, widgets) {
01260             InsertWidgetCommand *cmd = new InsertWidgetCommand(this);
01261             cmd->init(w);
01262             m_commandHistory->push(cmd);
01263             selectWidget(w);
01264         }
01265         endCommand();
01266 
01267         /* This will put the freshly pasted widgets into the clipboard, replacing the original.
01268            The point here is that the copied widgets are shifted a little with respect to the original.
01269            If the user presses paste again, the pasted widgets will be shifted again, rather than
01270            appearing on top of the previously pasted widgets. */
01271         copy();
01272 
01273     } else {
01274         QMessageBox::information(this, tr("Paste error"),
01275                                   tr("Can't paste widgets. Designer couldn't find a container\n"
01276                                       "to paste into which does not contain a layout. Break the layout\n"
01277                                       "of the container you want to paste into and select this container\n"
01278                                       "and then paste again."));
01279     }
01280 
01281 }
01282 
01283 void FormWindow::manageWidget(QWidget *w)
01284 {
01285     if (isManaged(w))
01286         return;
01287 
01288     Q_ASSERT(qobject_cast<QMenu*>(w) == 0);
01289 
01290     if (w->hasFocus())
01291         setFocus();
01292 
01293     core()->metaDataBase()->add(w);
01294 
01295     m_insertedWidgets.insert(w);
01296     m_widgets.append(w);
01297 
01298     setCursorToAll(Qt::ArrowCursor, w);
01299 
01300     if (QDesignerPromotedWidget *promoted = qobject_cast<QDesignerPromotedWidget*>(w))
01301         manageWidget(promoted->child());
01302 
01303     emit changed();
01304     emit widgetManaged(w);
01305 }
01306 
01307 void FormWindow::unmanageWidget(QWidget *w)
01308 {
01309     if (!isManaged(w))
01310         return;
01311 
01312     if (usedSelections.contains(w))
01313         usedSelections.value(w)->setWidget(0);
01314 
01315     emit aboutToUnmanageWidget(w);
01316 
01317     core()->metaDataBase()->remove(w);
01318 
01319     m_insertedWidgets.remove(w);
01320     m_widgets.removeAt(m_widgets.indexOf(w));
01321 
01322     emit changed();
01323     emit widgetUnmanaged(w);
01324 }
01325 
01326 bool FormWindow::isManaged(QWidget *w) const
01327 {
01328     return m_insertedWidgets.contains(w);
01329 }
01330 
01331 void FormWindow::breakLayout(QWidget *w)
01332 {
01333     if (w == this)
01334         w = mainContainer();
01335 
01336     w = core()->widgetFactory()->containerOfWidget(w);
01337 
01338     beginCommand(tr("Break layout"));
01339 
01340     for (;;) {
01341         if (!w || w == this)
01342             break;
01343 
01344         if (LayoutInfo::layoutType(m_core, core()->widgetFactory()->containerOfWidget(w)) != LayoutInfo::NoLayout
01345                 && core()->widgetDataBase()->isContainer(w, false)) {
01346 
01347             if (BreakLayoutCommand *cmd = breakLayoutCommand(w)) {
01348                 commandHistory()->push(cmd);
01349             }
01350 
01351             if (!qobject_cast<QLayoutWidget*>(w) && !qobject_cast<QSplitter*>(w))
01352                 break;
01353         }
01354 
01355         w = w->parentWidget();
01356     }
01357 
01358     clearSelection(false);
01359     endCommand();
01360 }
01361 
01362 BreakLayoutCommand *FormWindow::breakLayoutCommand(QWidget *w)
01363 {
01364     QList<QWidget*> widgets;
01365 
01366     QListIterator<QObject*> it(w->children());
01367     while (it.hasNext()) {
01368         QObject *obj = it.next();
01369 
01370         if (!obj->isWidgetType()
01371                 || !core()->metaDataBase()->item(obj))
01372             continue;
01373 
01374         widgets.append(static_cast<QWidget*>(obj));
01375     }
01376 
01377     BreakLayoutCommand *cmd = new BreakLayoutCommand(this);
01378     cmd->init(widgets, core()->widgetFactory()->widgetOfContainer(w));
01379     return cmd;
01380 }
01381 
01382 void FormWindow::breakLayout()
01383 {
01384     QWidget *w = currentWidget() ? currentWidget() : mainContainer();
01385 
01386     if (LayoutInfo::layoutType(m_core, w) != LayoutInfo::NoLayout ||
01387          w->parentWidget() && LayoutInfo::layoutType(m_core, w->parentWidget()) != LayoutInfo::NoLayout) {
01388         breakLayout(w);
01389         return;
01390     } else {
01391         QList<QWidget*> widgets = selectedWidgets();
01392         QListIterator<QWidget*> it(widgets);
01393         while (it.hasNext()) {
01394             QWidget *w = it.next();
01395             if (LayoutInfo::layoutType(m_core, w) != LayoutInfo::NoLayout ||
01396                  w->parentWidget() && LayoutInfo::layoutType(m_core, w->parentWidget()) != LayoutInfo::NoLayout)
01397                 break;
01398         }
01399         if (w) {
01400             breakLayout(w);
01401             return;
01402         }
01403     }
01404 
01405     w = mainContainer();
01406 
01407     if (LayoutInfo::layoutType(m_core, w) != LayoutInfo::NoLayout ||
01408          w->parentWidget() && LayoutInfo::layoutType(m_core, w->parentWidget()) != LayoutInfo::NoLayout)
01409         breakLayout(w);
01410 }
01411 
01412 void FormWindow::beginCommand(const QString &description)
01413 {
01414     m_commandHistory->beginMacro(description);
01415 }
01416 
01417 void FormWindow::endCommand()
01418 {
01419     m_commandHistory->endMacro();
01420 }
01421 
01422 void FormWindow::raiseWidgets()
01423 {
01424     QList<QWidget*> widgets = selectedWidgets();
01425     simplifySelection(&widgets);
01426 
01427     foreach (QWidget *widget, widgets) {
01428         widget->raise();
01429     }
01430 }
01431 
01432 void FormWindow::lowerWidgets()
01433 {
01434     QList<QWidget*> widgets = selectedWidgets();
01435     simplifySelection(&widgets);
01436 
01437     foreach (QWidget *widget, widgets) {
01438         widget->lower();
01439     }
01440 }
01441 
01442 bool FormWindow::handleMouseButtonDblClickEvent(QWidget *, QWidget *managedWidget, QMouseEvent *e)
01443 {
01444     e->accept();
01445 
01446     clearSelection(false);
01447     selectWidget(managedWidget);
01448 
01449     emit activated(managedWidget);
01450     return true;
01451 }
01452 
01453 void FormWindow::finishContextMenu(QWidget *w, QWidget *, QContextMenuEvent *e)
01454 {
01455     e->accept();
01456 
01457     QDesignerTaskMenuExtension *taskMenu = qt_extension<QDesignerTaskMenuExtension*>(core()->extensionManager(), w);
01458     QMenu *menu = createPopupMenu(w);
01459     if (menu && taskMenu) {
01460         QList<QAction *> acts = taskMenu->taskActions();
01461         if (QDesignerPromotedWidget *promoted = qobject_cast<QDesignerPromotedWidget*>(w)) {
01462             QDesignerTaskMenuExtension *baseTaskMenu =
01463                 qt_extension<QDesignerTaskMenuExtension*>(core()->extensionManager(),
01464                                                           promoted->child());
01465             if (baseTaskMenu) {
01466                 // "inherit" proper actions from base class's task menu
01467                 QList<QAction *> baseActs = baseTaskMenu->taskActions();
01468                 QList<QAction *>::iterator it;
01469                 for (it = baseActs.begin(); it != baseActs.end(); ) {
01470                     // special case: don't want the "Promote to custom widget" action
01471                     if ((*it)->objectName() == QLatin1String("__qt__promoteToCustomWidgetAction")) {
01472                         it = baseActs.erase(it);
01473                         continue;
01474                     }
01475                     // inherit the action only if it is not "reimplemented"
01476                     // by the promoted widget's task menu
01477                     QList<QAction *>::iterator it2;
01478                     bool inherit = true;
01479                     for (it2 = acts.begin(); it2 != acts.end(); ++it2) {
01480                         if ((*it)->text() == (*it2)->text()) {
01481                             inherit = false;
01482                             break;
01483                         }
01484                     }
01485                     if (inherit)
01486                         ++it;
01487                     else
01488                         it = baseActs.erase(it);
01489                 }
01490                 if (!baseActs.isEmpty()) {
01491                     // prepend the inherited actions to the action list
01492                     QAction *sep = new QAction(menu);
01493                     sep->setSeparator(true);
01494                     baseActs.append(sep);
01495                     for (int i = 0; i < baseActs.size(); ++i)
01496                         acts.insert(i, baseActs.at(i));
01497                 }
01498             }
01499         }
01500         QAction *sep = new QAction(menu);
01501         sep->setSeparator(true);
01502         acts.append(sep);
01503         menu->insertActions(menu->actions().at(0), acts);
01504     }
01505 
01506     if (menu) {
01507         emit contextMenuRequested(menu, w);
01508         menu->exec(e->globalPos());
01509         delete menu;
01510     }
01511 }
01512 
01513 
01514 bool FormWindow::handleContextMenu(QWidget *, QWidget *managedWidget, QContextMenuEvent *e)
01515 {
01516     e->accept();
01517 
01518     bool selected = isWidgetSelected(managedWidget);
01519     if (selected == false) {
01520         clearSelection(false);
01521 
01522         selectWidget(managedWidget);
01523         raiseChildSelections(managedWidget); // raise selections and select widget
01524 
01525         QMetaObject::invokeMethod(core()->formWindowManager(), "slotUpdateActions");
01526     }
01527 
01528     if (!isMainContainer(managedWidget)) { // press on a child widget
01529         // if widget is laid out, find the first non-laid out super-widget
01530         QWidget *realWidget = managedWidget; // but store the original one
01531         QMainWindow *mw = qobject_cast<QMainWindow*>(mainContainer());
01532 
01533         if (mw && mw->centralWidget() == realWidget) {
01534             finishContextMenu(managedWidget, this, e);
01535         } else {
01536             finishContextMenu(realWidget, realWidget, e);
01537         }
01538     } else {
01539         finishContextMenu(mainContainer(), mainContainer(), e);
01540     }
01541 
01542     return true;
01543 }
01544 
01545 void FormWindow::setContents(QIODevice *dev)
01546 {
01547     bool saved = updatesEnabled();
01548 
01549     setUpdatesEnabled(false);
01550     clearSelection();
01551 
01552     if (mainContainer()) {
01553         core()->metaDataBase()->remove(mainContainer());
01554         delete mainContainer();
01555         m_mainContainer = 0;
01556     }
01557 
01558     m_insertedWidgets.clear();
01559     m_widgets.clear();
01560     emit changed();
01561 
01562     QDesignerResource r(this);
01563     QWidget *w = r.load(dev, this);
01564     if (w == 0) {
01565         setFileName(QString());
01566         w = core()->widgetFactory()->createWidget(QLatin1String("QWidget"), this);
01567         w->resize(400, 300);
01568     }
01569 
01570     setMainContainer(w);
01571 
01572     setUpdatesEnabled(saved);
01573 }
01574 
01575 void FormWindow::setContents(const QString &contents)
01576 {
01577     QByteArray data = contents.toUtf8();
01578     QBuffer b(&data);
01579     if (b.open(QIODevice::ReadOnly))
01580         setContents(&b);
01581 }
01582 
01583 void FormWindow::layoutHorizontalContainer(QWidget *w)
01584 {
01585     if (w == this)
01586         w = mainContainer();
01587 
01588     w = core()->widgetFactory()->containerOfWidget(w);
01589 
01590     QList<QObject*> l = w->children();
01591     if (l.isEmpty())
01592         return;
01593 
01594     QList<QWidget*> widgets;
01595     QListIterator<QObject*> it(l);
01596     while (it.hasNext()) {
01597         QObject* o = it.next();
01598         if (!o->isWidgetType())
01599             continue;
01600 
01601         QWidget *widget = static_cast<QWidget*>(o);
01602         if (widget->isVisibleTo(this) && isManaged(widget))
01603             widgets.append(widget);
01604     }
01605 
01606     LayoutCommand *cmd = new LayoutCommand(this);
01607     cmd->init(mainContainer(), widgets, LayoutInfo::HBox, w);
01608     clearSelection(false);
01609     commandHistory()->push(cmd);
01610 }
01611 
01612 void FormWindow::layoutVerticalContainer(QWidget *w)
01613 {
01614     if (w == this)
01615         w = mainContainer();
01616 
01617     w = core()->widgetFactory()->containerOfWidget(w);
01618 
01619     QList<QObject*> l = w->children();
01620     if (l.isEmpty())
01621         return;
01622 
01623     QListIterator<QObject*> it(l);
01624     QList<QWidget*> widgets;
01625     while (it.hasNext()) {
01626         QObject* o = it.next();
01627         if (!o->isWidgetType())
01628             continue;
01629 
01630         QWidget *widget = static_cast<QWidget*>(o);
01631         if (widget->isVisibleTo(this) && isManaged(widget))
01632             widgets.append(widget);
01633     }
01634 
01635     LayoutCommand *cmd = new LayoutCommand(this);
01636     cmd->init(mainContainer(), widgets, LayoutInfo::VBox, w);
01637     clearSelection(false);
01638     commandHistory()->push(cmd);
01639 }
01640 
01641 void FormWindow::layoutGridContainer(QWidget *w)
01642 {
01643     if (w == this)
01644         w = mainContainer();
01645 
01646     w = core()->widgetFactory()->containerOfWidget(w);
01647 
01648     QList<QObject*> l = w->children();
01649     if (l.isEmpty())
01650         return;
01651 
01652     QList<QWidget*> widgets;
01653     QListIterator<QObject*> it(l);
01654     while (it.hasNext()) {
01655         QObject* o = it.next();
01656 
01657         if (!o->isWidgetType())
01658             continue;
01659 
01660         QWidget *widget = static_cast<QWidget*>(o);
01661         if (widget->isVisibleTo(this) && isManaged(widget))
01662             widgets.append(widget);
01663     }
01664 
01665     LayoutCommand *cmd = new LayoutCommand(this);
01666     cmd->init(mainContainer(), widgets, LayoutInfo::Grid, w);
01667     clearSelection(false);
01668     commandHistory()->push(cmd);
01669 }
01670 
01671 bool FormWindow::hasInsertedChildren(QWidget *widget) const // ### move
01672 {
01673     if (QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), widget)) {
01674         widget = container->widget(container->currentIndex());
01675     }
01676 
01677     QList<QWidget*> l = widgets(widget);
01678 
01679     foreach (QWidget *child, l) {
01680         if (isManaged(child) && !LayoutInfo::isWidgetLaidout(core(), child) && child->isVisibleTo(const_cast<FormWindow*>(this)))
01681             return true;
01682     }
01683 
01684     return false;
01685 }
01686 
01687 void FormWindow::layoutHorizontalSplit()
01688 {
01689     LayoutCommand *cmd = new LayoutCommand(this);
01690     cmd->init(mainContainer(), selectedWidgets(), LayoutInfo::HBox, /*layoutBase=*/ 0, /*splitter=*/ true);
01691     clearSelection(false);
01692     commandHistory()->push(cmd);
01693 }
01694 
01695 void FormWindow::layoutVerticalSplit()
01696 {
01697     LayoutCommand *cmd = new LayoutCommand(this);
01698     cmd->init(mainContainer(), selectedWidgets(), LayoutInfo::VBox, /*layoutBase=*/ 0, /*splitter=*/ true);
01699     clearSelection(false);
01700     commandHistory()->push(cmd);
01701 }
01702 
01703 QMenu *FormWindow::createPopupMenu(QWidget *w)
01704 {
01705     QDesignerFormWindowManagerInterface *manager = core()->formWindowManager();
01706     bool isFormWindow = qobject_cast<FormWindow*>(w);
01707 
01708     QMenu *popup = new QMenu(this);
01709 
01710     if (QDesignerPromotedWidget *promoted = qobject_cast<QDesignerPromotedWidget*>(w))
01711         w = promoted->child();
01712 
01713     if (qobject_cast<QDesignerTabWidget*>(w)) {
01714         QDesignerTabWidget *tabWidget = static_cast<QDesignerTabWidget*>(w);
01715         if (tabWidget->count()) {
01716             popup->addAction(tabWidget->actionDeletePage());
01717         }
01718         QMenu *insertPageMenu = popup->addMenu(tr("Insert Page"));
01719         insertPageMenu->addAction(tabWidget->actionInsertPageAfter());
01720         insertPageMenu->addAction(tabWidget->actionInsertPage());
01721         popup->addSeparator();
01722     } else if (qobject_cast<QDesignerStackedWidget*>(w)) {
01723         QDesignerStackedWidget *stackedWidget = static_cast<QDesignerStackedWidget*>(w);
01724         if (stackedWidget->count()) {
01725             popup->addAction(stackedWidget->actionDeletePage());
01726         }
01727         QMenu *insertPageMenu = popup->addMenu(tr("Insert Page"));
01728         insertPageMenu->addAction(stackedWidget->actionInsertPageAfter());
01729         insertPageMenu->addAction(stackedWidget->actionInsertPage());
01730         popup->addAction(stackedWidget->actionNextPage());
01731         popup->addAction(stackedWidget->actionPreviousPage());
01732         if (stackedWidget->count() > 1) {
01733             popup->addAction(stackedWidget->actionChangePageOrder());
01734         }
01735         popup->addSeparator();
01736     } else if (qobject_cast<QDesignerToolBox*>(w)) {
01737         QDesignerToolBox *toolBox = static_cast<QDesignerToolBox*>(w);
01738         if (toolBox->count()) {
01739             popup->addAction(toolBox->actionDeletePage());
01740         }
01741         QMenu *insertPageMenu = popup->addMenu(tr("Insert Page"));
01742         insertPageMenu->addAction(toolBox->actionInsertPageAfter());
01743         insertPageMenu->addAction(toolBox->actionInsertPage());
01744         if (toolBox->count() > 1) {
01745             popup->addAction(toolBox->actionChangePageOrder());
01746         }
01747         popup->addSeparator();
01748     }
01749 
01750     if (!isFormWindow) {
01751         popup->addAction(manager->actionCut());
01752         popup->addAction(manager->actionCopy());
01753     }
01754 
01755     popup->addAction(manager->actionPaste());
01756     popup->addAction(manager->actionSelectAll());
01757 
01758     if (!isFormWindow) {
01759         popup->addAction(manager->actionDelete());
01760     }
01761 
01762     popup->addSeparator();
01763     QMenu *menu = popup->addMenu(tr("Lay out"));
01764     menu->addAction(manager->actionAdjustSize());
01765     menu->addAction(manager->actionHorizontalLayout());
01766     menu->addAction(manager->actionVerticalLayout());
01767     menu->addAction(manager->actionGridLayout());
01768 
01769     if (!isFormWindow) {
01770         menu->addAction(manager->actionSplitHorizontal());
01771         menu->addAction(manager->actionSplitVertical());
01772     }
01773 
01774     menu->addAction(manager->actionBreakLayout());
01775 
01776     return popup;
01777 }
01778 
01779 void FormWindow::resizeEvent(QResizeEvent *e)
01780 {
01781 /*    if (editMode() == TabOrderEditMode)
01782         repositionOrderIndicators(); */
01783 
01784     m_geometryChangedTimer->start(10);
01785 
01786     QWidget::resizeEvent(e);
01787 }
01788 
01795 QPoint FormWindow::mapToForm(const QWidget *w, const QPoint &pos) const
01796 {
01797     QPoint p = pos;
01798     const QWidget* i = w;
01799     while (i && !i->isWindow() && !isMainContainer(i)) {
01800         p = i->mapToParent(p);
01801         i = i->parentWidget();
01802     }
01803 
01804     return mapFromGlobal(w->mapToGlobal(pos));
01805 }
01806 
01807 bool FormWindow::canBeBuddy(QWidget *w) const // ### rename me.
01808 {
01809     if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), w)) {
01810         int index = sheet->indexOf(QLatin1String("focusPolicy"));
01811         if (index != -1) {
01812             bool ok = false;
01813             Qt::FocusPolicy q = (Qt::FocusPolicy) Utils::valueOf(sheet->property(index), &ok);
01814             return ok && q != Qt::NoFocus;
01815         }
01816     }
01817 
01818     return false;
01819 }
01820 
01821 QWidget *FormWindow::findContainer(QWidget *w, bool excludeLayout) const
01822 {
01823     if (!isChildOf(w, this)
01824         || const_cast<const QWidget *>(w) == this)
01825         return 0;
01826 
01827     QDesignerWidgetFactoryInterface *widgetFactory = core()->widgetFactory();
01828     QDesignerWidgetDataBaseInterface *widgetDataBase = core()->widgetDataBase();
01829     QDesignerMetaDataBaseInterface *metaDataBase = core()->metaDataBase();
01830 
01831     QWidget *container = widgetFactory->containerOfWidget(mainContainer()); // default parent for new widget is the formwindow
01832     if (!isMainContainer(w)) { // press was not on formwindow, check if we can find another parent
01833         while (w) {
01834             if (qobject_cast<InvisibleWidget*>(w) || !metaDataBase->item(w)) {
01835                 w = w->parentWidget();
01836                 continue;
01837             }
01838 
01839             bool isContainer = widgetDataBase->isContainer(w, true) || w == mainContainer();
01840 
01841             if (!isContainer || (excludeLayout && qobject_cast<QLayoutWidget*>(w))) { // ### skip QSplitter
01842                 w = w->parentWidget();
01843             } else {
01844                 container = w;
01845                 break;
01846             }
01847         }
01848     }
01849 
01850     return container;
01851 }
01852 
01853 void FormWindow::simplifySelection(QList<QWidget*> *sel) const
01854 {
01855     // Figure out which widgets should be removed from selection.
01856     // We want to remove those whose parent widget is also in the
01857     // selection (because the child widgets are contained by
01858     // their parent, they shouldn't be in the selection --
01859     // they are "implicitly" selected)
01860     QList<QWidget*> toBeRemoved;
01861     QListIterator<QWidget*> it(*sel);
01862     while (it.hasNext()) {
01863         QWidget *child = it.next();
01864         QWidget *w = child;
01865 
01866         while (w->parentWidget() && sel->contains(w->parentWidget()))
01867             w = w->parentWidget();
01868 
01869         if (child != w)
01870             toBeRemoved.append(child);
01871     }
01872     // Now we can actually remove the widgets that were marked
01873     // for removal in the previous pass.
01874     while (!toBeRemoved.isEmpty())
01875         sel->removeAll(toBeRemoved.takeFirst());
01876 }
01877 
01878 FormWindow *FormWindow::findFormWindow(QWidget *w)
01879 {
01880     return qobject_cast<FormWindow*>(QDesignerFormWindowInterface::findFormWindow(w));
01881 }
01882 
01883 void FormWindow::repaintSelection()
01884 {
01885     QList<QWidget*> sel = selectedWidgets();
01886     foreach (QWidget *ww, sel)
01887         repaintSelection(ww);
01888 }
01889 
01890 bool FormWindow::isDirty() const
01891 {
01892     return m_dirty;
01893 }
01894 
01895 void FormWindow::setDirty(bool dirty)
01896 {
01897     m_dirty = dirty;
01898 
01899     if (!m_dirty)
01900         m_lastIndex = m_commandHistory->index();
01901 }
01902 
01903 void FormWindow::updateDirty()
01904 {
01905     m_dirty = m_commandHistory->index() != m_lastIndex;
01906 }
01907 
01908 QWidget *FormWindow::containerAt(const QPoint &pos)
01909 {
01910     QWidget *widget = widgetAt(pos);
01911     return findContainer(widget, true);
01912 }
01913 
01914 static QWidget *childAt_SkipDropLine(QWidget *w, QPoint pos)
01915 {
01916     QObjectList child_list = w->children();
01917     for (int i = child_list.size() - 1; i >= 0; --i) {
01918         QObject *child_obj = child_list[i];
01919         if (qobject_cast<WidgetHandle*>(child_obj) != 0)
01920             continue;
01921         QWidget *child = qobject_cast<QWidget*>(child_obj);
01922         if (!child || child->isWindow() || !child->isVisible() ||
01923                 !child->geometry().contains(pos) || child->testAttribute(Qt::WA_TransparentForMouseEvents))
01924             continue;
01925         QPoint childPos = child->mapFromParent(pos);
01926         if (QWidget *res = childAt_SkipDropLine(child, childPos))
01927             return res;
01928         if (child->testAttribute(Qt::WA_MouseNoMask) || child->mask().contains(pos)
01929                 || child->mask().isEmpty())
01930             return child;
01931     }
01932 
01933     return 0;
01934 }
01935 
01936 QWidget *FormWindow::widgetAt(const QPoint &pos)
01937 {
01938     QWidget *w = childAt(pos);
01939     if (qobject_cast<WidgetHandle*>(w) != 0)
01940         w = childAt_SkipDropLine(this, pos);
01941     return w == 0 ? this : w;
01942 }
01943 
01944 void FormWindow::highlightWidget(QWidget *widget, const QPoint &pos, HighlightMode mode)
01945 {
01946     Q_ASSERT(widget);
01947 
01948     if (QMainWindow *mainWindow = qobject_cast<QMainWindow*> (widget)) {
01949         widget = mainWindow->centralWidget();
01950     }
01951 
01952     QWidget *container = findContainer(widget, false);
01953 
01954     if (container == 0 || core()->metaDataBase()->item(container) == 0)
01955         return;
01956 
01957     if (QDesignerActionProviderExtension *g = qt_extension<QDesignerActionProviderExtension*>(core()->extensionManager(), container)) {
01958         if (mode == Restore) {
01959             g->adjustIndicator(QPoint());
01960         } else {
01961             QPoint pt = widget->mapTo(container, pos);
01962             g->adjustIndicator(pt);
01963         }
01964     } else if (QDesignerLayoutDecorationExtension *g = qt_extension<QDesignerLayoutDecorationExtension*>(core()->extensionManager(), container)) {
01965         if (mode == Restore) {
01966             g->adjustIndicator(QPoint(), -1);
01967         } else {
01968             QPoint pt = widget->mapTo(container, pos);
01969             int index = g->findItemAt(pt);
01970             g->adjustIndicator(pt, index);
01971         }
01972     }
01973 
01974     QMainWindow *mw = qobject_cast<QMainWindow*> (container);
01975     if (container == mainContainer() || (mw && mw->centralWidget() && mw->centralWidget() == container))
01976         return;
01977 
01978     if (mode == Restore) {
01979         QPair<QPalette, bool> paletteAndFill = palettesBeforeHighlight.take(container);
01980         container->setPalette(paletteAndFill.first);
01981         container->setAutoFillBackground(paletteAndFill.second);
01982     } else {
01983         QPalette p = container->palette();
01984         if (!palettesBeforeHighlight.contains(container)) {
01985             QPair<QPalette, bool> paletteAndFill;
01986             if (container->testAttribute(Qt::WA_SetPalette))
01987                 paletteAndFill.first = p;
01988             paletteAndFill.second = container->autoFillBackground();
01989             palettesBeforeHighlight[container] = paletteAndFill;
01990         }
01991 
01992         p.setColor(backgroundRole(), p.midlight().color());
01993         container->setPalette(p);
01994         container->setAutoFillBackground(true);
01995     }
01996 }
01997 
01998 QList<QWidget *> FormWindow::widgets(QWidget *widget) const
01999 {
02000     QList<QWidget *> l;
02001 
02002     foreach (QObject *o, widget->children()) {
02003         QWidget *w = qobject_cast<QWidget*>(o);
02004         if (w && isManaged(w))
02005             l.append(w);
02006     }
02007 
02008     return l;
02009 }
02010 
02011 int FormWindow::toolCount() const
02012 {
02013     return m_widgetStack->count();
02014 }
02015 
02016 QDesignerFormWindowToolInterface *FormWindow::tool(int index) const
02017 {
02018     return m_widgetStack->tool(index);
02019 }
02020 
02021 void FormWindow::registerTool(QDesignerFormWindowToolInterface *tool)
02022 {
02023     Q_ASSERT(tool != 0);
02024 
02025     m_widgetStack->addTool(tool);
02026 
02027     if (m_mainContainer)
02028         m_mainContainer->update();
02029 }
02030 
02031 void FormWindow::setCurrentTool(int index)
02032 {
02033     m_widgetStack->setCurrentTool(index);
02034 }
02035 
02036 int FormWindow::currentTool() const
02037 {
02038     return m_widgetStack->currentIndex();
02039 }
02040 
02041 bool FormWindow::handleEvent(QWidget *widget, QWidget *managedWidget, QEvent *event)
02042 {
02043     if (m_widgetStack == 0)
02044         return false;
02045 
02046     QDesignerFormWindowToolInterface *tool = m_widgetStack->currentTool();
02047     if (tool == 0)
02048         return false;
02049 
02050     return tool->handleEvent(widget, managedWidget, event);
02051 }
02052 
02053 void FormWindow::initializeCoreTools()
02054 {
02055     m_widgetEditor = new WidgetEditorTool(this);
02056     registerTool(m_widgetEditor);
02057 }
02058 
02059 void FormWindow::checkSelection()
02060 {
02061     m_checkSelectionTimer->start(0);
02062 }
02063 
02064 void FormWindow::checkSelectionNow()
02065 {
02066     m_checkSelectionTimer->stop();
02067 
02068     foreach (QWidget *widget, selectedWidgets()) {
02069         updateSelection(widget);
02070 
02071         if (LayoutInfo::layoutType(core(), widget) != LayoutInfo::NoLayout)
02072             updateChildSelections(widget);
02073     }
02074 }
02075 
02076 QString FormWindow::author() const
02077 {
02078     return m_author;
02079 }
02080 
02081 QString FormWindow::comment() const
02082 {
02083      return m_comment;
02084 }
02085 
02086 void FormWindow::setAuthor(const QString &author)
02087 {
02088     m_author = author;
02089 }
02090 
02091 void FormWindow::setComment(const QString &comment)
02092 {
02093     m_comment = comment;
02094 }
02095 
02096 void FormWindow::editWidgets()
02097 {
02098     m_widgetEditor->action()->trigger();
02099 }
02100 
02101 QStringList FormWindow::resourceFiles() const
02102 {
02103     return m_resourceFiles;
02104 }
02105 
02106 void FormWindow::addResourceFile(const QString &path)
02107 {
02108     if (!m_resourceFiles.contains(path)) {
02109         m_resourceFiles.append(path);
02110         setDirty(true);
02111         emit resourceFilesChanged();
02112     }
02113 }
02114 
02115 void FormWindow::removeResourceFile(const QString &path)
02116 {
02117     if (m_resourceFiles.removeAll(path) > 0) {
02118         setDirty(true);
02119         emit resourceFilesChanged();
02120     }
02121 }
02122 
02123 bool FormWindow::blockSelectionChanged(bool b)
02124 {
02125     bool blocked = m_blockSelectionChanged;
02126     m_blockSelectionChanged = b;
02127     return blocked;
02128 }
02129 
02130 void FormWindow::editContents()
02131 {
02132     QList<QWidget*> sel = selectedWidgets();
02133     if (sel.count() == 1) {
02134         QWidget *widget = sel.first();
02135 
02136         if (QDesignerTaskMenuExtension *taskMenu = qt_extension<QDesignerTaskMenuExtension*>(core()->extensionManager(), widget)) {
02137             if (QAction *a = taskMenu->preferredEditAction()) {
02138                 a->trigger();
02139             } else if (QDesignerPromotedWidget *promoted = qobject_cast<QDesignerPromotedWidget*>(widget)) {
02140                 QDesignerTaskMenuExtension *baseTaskMenu =
02141                     qt_extension<QDesignerTaskMenuExtension*>(core()->extensionManager(),
02142                                                               promoted->child());
02143                 if (QAction *b = baseTaskMenu->preferredEditAction())
02144                     b->trigger();
02145             }
02146         }
02147     }
02148 }
02149 
02150 void FormWindow::dropWidgets(QList<QDesignerDnDItemInterface*> &item_list, QWidget *target,
02151                                 const QPoint &global_mouse_pos)
02152 {
02153     beginCommand(tr("Drop widget"));
02154 
02155     QWidget *parent = target;
02156     if (parent == 0)
02157         parent = mainContainer();
02158 
02159     // You can only drop stuff onto the central widget of a QMainWindow
02160     // ### generalize to use container extension
02161     if (QMainWindow *main_win = qobject_cast<QMainWindow*>(target)) {
02162         QPoint main_win_pos = main_win->mapFromGlobal(global_mouse_pos);
02163         QRect central_wgt_geo = main_win->centralWidget()->geometry();
02164         if (!central_wgt_geo.contains(main_win_pos)) {
02165             foreach (QDesignerDnDItemInterface *item, item_list) {
02166                 if (item->widget() != 0)
02167                     item->widget()->show();
02168             }
02169             return;
02170         }
02171     }
02172 
02173     core()->formWindowManager()->setActiveFormWindow(this);
02174     mainContainer()->activateWindow();
02175     clearSelection(false);
02176 
02177     highlightWidget(target, target->mapFromGlobal(global_mouse_pos), FormWindow::Restore);
02178 
02179     foreach (QDesignerDnDItemInterface *item, item_list) {
02180         DomUI *dom_ui = item->domUi();
02181         QRect geometry = item->decoration()->geometry();
02182         Q_ASSERT(dom_ui != 0);
02183 
02184         if (item->type() == QDesignerDnDItemInterface::CopyDrop) {
02185             QWidget *widget = createWidget(dom_ui, geometry, parent);
02186             if (!widget)
02187                 return;
02188             selectWidget(widget, true);
02189             mainContainer()->setFocus(Qt::MouseFocusReason); // in case focus was in e.g. object inspector
02190         } else {
02191             QWidget *widget = item->widget();
02192             Q_ASSERT(widget != 0);
02193             QDesignerFormWindowInterface *dest = findFormWindow(widget);
02194 
02195             QWidget *container = findContainer(parent, false);
02196             QDesignerLayoutDecorationExtension *deco = qt_extension<QDesignerLayoutDecorationExtension*>(core()->extensionManager(), container);
02197 
02198             if (dest == this) {
02199                 if (deco == 0) {
02200                     parent = container;
02201 
02202                     if (parent != widget->parent()) {
02203                         ReparentWidgetCommand *cmd = new ReparentWidgetCommand(dest);
02204                         cmd->init(widget, parent);
02205                         commandHistory()->push(cmd);
02206                     }
02207 
02208                     geometry.moveTopLeft(parent->mapFromGlobal(geometry.topLeft()));
02209                     resizeWidget(widget, geometry);
02210                     selectWidget(widget, true);
02211                     widget->show();
02212                 } else {
02213                     insertWidget(widget, geometry, container, true);
02214                 }
02215             } else {
02216                 FormWindow *source = qobject_cast<FormWindow*>(item->source());
02217                 Q_ASSERT(source != 0);
02218 
02219                 source->deleteWidgets(QList<QWidget*>() << widget);
02220                 QWidget *new_widget = createWidget(dom_ui, geometry, parent);
02221 
02222                 selectWidget(new_widget, true);
02223             }
02224         }
02225     }
02226 
02227     endCommand();
02228 }
02229 
02230 QDir FormWindow::absoluteDir() const
02231 {
02232     if (fileName().isEmpty())
02233         return QDir::current();
02234 
02235     return QFileInfo(fileName()).absoluteDir();
02236 }
02237 
02238 void FormWindow::layoutDefault(int *margin, int *spacing)
02239 {
02240     *margin = m_defaultMargin;
02241     *spacing = m_defaultSpacing;
02242 }
02243 
02244 void FormWindow::setLayoutDefault(int margin, int spacing)
02245 {
02246     m_defaultMargin = margin;
02247     m_defaultSpacing = spacing;
02248 }
02249 
02250 void FormWindow::layoutFunction(QString *margin, QString *spacing)
02251 {
02252     *margin = m_marginFunction;
02253     *spacing = m_spacingFunction;
02254 }
02255 
02256 void FormWindow::setLayoutFunction(const QString &margin, const QString &spacing)
02257 {
02258     m_marginFunction = margin;
02259     m_spacingFunction = spacing;
02260 }
02261 
02262 QString FormWindow::pixmapFunction() const
02263 {
02264     return m_pixmapFunction;
02265 }
02266 
02267 void FormWindow::setPixmapFunction(const QString &pixmapFunction)
02268 {
02269     m_pixmapFunction = pixmapFunction;
02270 }
02271 
02272 QStringList FormWindow::includeHints() const
02273 {
02274     return m_includeHints;
02275 }
02276 
02277 void FormWindow::setIncludeHints(const QStringList &includeHints)
02278 {
02279     m_includeHints = includeHints;
02280 }
02281 
02282 QString FormWindow::exportMacro() const
02283 {
02284     return m_exportMacro;
02285 }
02286 
02287 void FormWindow::setExportMacro(const QString &exportMacro)
02288 {
02289     m_exportMacro = exportMacro;
02290 }
02291 
02292 } // namespace

Generated on Thu Mar 15 12:01:01 2007 for Qt 4.2 User's Guide by  doxygen 1.5.1