⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 layout.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.**** This file is part of the Qt Designer of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.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 GNU** General Public Licensing requirements will be met:** http://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "layout_p.h"#include "qdesigner_widget_p.h"#include "qdesigner_utils_p.h"#include "qlayout_widget_p.h"#include "spacer_widget_p.h"#include "layoutdecoration.h"#include <QtDesigner/QtDesigner>#include <QtCore/qdebug.h>#include <QtCore/QVector>#include <QtGui/qevent.h>#include <QtGui/QGridLayout>#include <QtGui/QPainter>#include <QtGui/QBitmap>#include <QtGui/QSplitter>#include <QtGui/QMainWindow>#include <QtGui/QApplication>#include <QtGui/QScrollArea>namespace qdesigner_internal {class FriendlyBoxLayout: public QBoxLayout{public:    inline FriendlyBoxLayout(Direction d) : QBoxLayout(d) { Q_ASSERT(0); }    friend void insert_into_box_layout(QBoxLayout *box, int index, QWidget *widget);};void add_to_box_layout(QBoxLayout *box, QWidget *widget){    if (QLayoutWidget *layoutWidget = qobject_cast<QLayoutWidget*>(widget)) {        QLayoutWidgetItem *item = new QLayoutWidgetItem(layoutWidget);        item->addTo(box);        box->addItem(item);    } else {        box->addWidget(widget);    }}void insert_into_box_layout(QBoxLayout *box, int index, QWidget *widget){    if (QLayoutWidget *layoutWidget = qobject_cast<QLayoutWidget*>(widget)) {        QLayoutWidgetItem *item = new QLayoutWidgetItem(layoutWidget);        item->addTo(box);        static_cast<FriendlyBoxLayout*>(box)->insertItem(index, item);    } else {        box->insertWidget(index, widget);    }}void add_to_grid_layout(QGridLayout *grid, QWidget *widget, int r, int c, int rs, int cs, Qt::Alignment align){    if (QLayoutWidget *layoutWidget = qobject_cast<QLayoutWidget*>(widget)) {        QLayoutWidgetItem *item = new QLayoutWidgetItem(layoutWidget);        item->addTo(grid);        grid->addItem(item, r, c, rs, cs, align);    } else {        grid->addWidget(widget, r, c, rs, cs, align);    }}/*!  \class Layout layout.h  \brief Baseclass for layouting widgets in the Designer  Classes derived from this abstract base class are used for layouting  operations in the Designer.*//*!  \a p specifies the parent of the layoutBase \a lb. The parent  might be changed in setup(). If the layoutBase is a  container, the parent and the layoutBase are the same. Also they  always have to be a widget known to the designer (e.g. in the case  of the tabwidget parent and layoutBase are the tabwidget and not the  page which actually gets laid out. For actual usage the correct  widget is found later by Layout.) */Layout::Layout(const QList<QWidget*> &wl, QWidget *p, QDesignerFormWindowInterface *fw, QWidget *lb, bool splitter)    : m_widgets(wl), m_parentWidget(p), formWindow(fw), isBreak(false), useSplitter(splitter){    layoutBase = lb;    if (layoutBase)        oldGeometry = layoutBase->geometry();}Layout::~Layout(){}int Layout::margin() const{    if (layoutBase && layoutBase->layout())        return layoutBase->layout()->margin();    qWarning("unknown margin");    return 0;}int Layout::spacing() const{    if (layoutBase && layoutBase->layout())        return layoutBase->layout()->spacing();    qWarning("unknown spacing");    return 0;}/*!  The widget list we got in the constructor might contain too much  widgets (like widgets with different parents, already laid out  widgets, etc.). Here we set up the list and so the only the "best"  widgets get laid out.*/void Layout::setup(){    startPoint = QPoint(32767, 32767);    // Go through all widgets of the list we got. As we can only    // layout widgets which have the same parent, we first do some    // sorting which means create a list for each parent containing    // its child here. After that we keep working on the list of    // childs which has the most entries.    // Widgets which are already laid out are thrown away here too    QMultiMap<QWidget*, QWidget*> lists;    foreach (QWidget *w, m_widgets) {        QWidget *p = w->parentWidget();        if (p && LayoutInfo::layoutType(formWindow->core(), p) != LayoutInfo::NoLayout                && formWindow->core()->metaDataBase()->item(p->layout()) != 0)            continue;        lists.insert(p, w);    }    QList<QWidget*> lastList;    QList<QWidget*> parents = lists.keys();    foreach (QWidget *p, parents) {        QList<QWidget*> children = lists.values(p);        if (children.count() > lastList.count())            lastList = children;    }    // If we found no list (because no widget did fit at all) or the    // best list has only one entry and we do not layout a container,    // we leave here.    QDesignerWidgetDataBaseInterface *widgetDataBase = formWindow->core()->widgetDataBase();    if (lastList.count() < 2 &&                        (!layoutBase ||                          (!widgetDataBase->isContainer(layoutBase, false) &&                            layoutBase != formWindow->mainContainer()))                       ) {        m_widgets.clear();        startPoint = QPoint(0, 0);        return;    }    // Now we have a new and clean widget list, which makes sense    // to layout    m_widgets = lastList;    // Also use the only correct parent later, so store it    Q_ASSERT(m_widgets.isEmpty() == false);    m_parentWidget = formWindow->core()->widgetFactory()->widgetOfContainer(m_widgets.first()->parentWidget());    // Now calculate the position where the layout-meta-widget should    // be placed and connect to widgetDestroyed() signals of the    // widgets to get informed if one gets deleted to be able to    // handle that and do not crash in this case    foreach (QWidget *w, m_widgets) {        connect(w, SIGNAL(destroyed()), this, SLOT(widgetDestroyed()));        startPoint = QPoint(qMin(startPoint.x(), w->x()), qMin(startPoint.y(), w->y()));        QRect rc(w->geometry());        geometries.insert(w, rc);        // Change the Z-order, as saving/loading uses the Z-order for        // writing/creating widgets and this has to be the same as in        // the layout. Else saving + loading will give different results        w->raise();    }    sort();}void Layout::widgetDestroyed(){     if (sender() && sender()->isWidgetType()) {         QWidget *w = static_cast<QWidget *>(sender());         m_widgets.removeAt(m_widgets.indexOf(w));         geometries.remove(w);     }}bool Layout::prepareLayout(bool &needMove, bool &needReparent){    if (!m_widgets.count())        return false;    foreach (QWidget *widget, m_widgets) {        widget->raise();    }    needMove = !layoutBase;    needReparent = needMove || qobject_cast<QLayoutWidget*>(layoutBase) || qobject_cast<QSplitter*>(layoutBase);    QDesignerWidgetFactoryInterface *widgetFactory = formWindow->core()->widgetFactory();    QDesignerMetaDataBaseInterface *metaDataBase = formWindow->core()->metaDataBase();    if (layoutBase == 0) {        QString baseWidgetClassName = QLatin1String("QLayoutWidget");        if (useSplitter)            baseWidgetClassName = QLatin1String("QSplitter");        layoutBase = widgetFactory->createWidget(baseWidgetClassName, widgetFactory->containerOfWidget(m_parentWidget));        if (useSplitter) {            layoutBase->setObjectName("splitter");            formWindow->ensureUniqueObjectName(layoutBase);        }    } else {        LayoutInfo::deleteLayout(formWindow->core(), layoutBase);    }    metaDataBase->add(layoutBase);    Q_ASSERT(layoutBase->layout() == 0 || metaDataBase->item(layoutBase->layout()) == 0);    return true;}static bool isMainContainer(QDesignerFormWindowInterface *fw, const QWidget *w){    return w && (w == fw || w == fw->mainContainer());}static bool isPageOfContainerWidget(QDesignerFormWindowInterface *fw, QWidget *widget){    QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(            fw->core()->extensionManager(), widget->parentWidget());    if (c != 0) {        for (int i = 0; i<c->count(); ++i) {            if (widget == c->widget(i))                return true;        }    }    return false;}void Layout::finishLayout(bool needMove, QLayout *layout){    if (m_parentWidget == layoutBase) {        QWidget *widget = layoutBase;        oldGeometry = widget->geometry();        bool done = false;        while (!isMainContainer(formWindow, widget) && !done) {            QDesignerContainerExtension *c = 0;            c = qt_extension<QDesignerContainerExtension*>(formWindow->core()->extensionManager(),                        widget->parentWidget());            if (!formWindow->isManaged(widget)) {                widget = widget->parentWidget();                continue;            } else if (LayoutInfo::isWidgetLaidout(formWindow->core(), widget)) {                widget = widget->parentWidget();                continue;            } else if (isPageOfContainerWidget(formWindow, widget)) {                widget = widget->parentWidget();                continue;            } else if (widget->parentWidget()) {                QScrollArea *area = qobject_cast<QScrollArea*>(widget->parentWidget()->parentWidget());                if (area && area->widget() == widget) {                    widget = area;                    continue;                }            }            done = true;        }        QApplication::processEvents();        // We don't want to resize the form window        if (!Utils::isCentralWidget(formWindow, widget))            widget->adjustSize();        return;    }    if (needMove)        layoutBase->move(startPoint);    QRect g(layoutBase->pos(), layoutBase->size());    if (LayoutInfo::layoutType(formWindow->core(), layoutBase->parentWidget()) == LayoutInfo::NoLayout && !isBreak)        layoutBase->adjustSize();    else if (isBreak)        layoutBase->setGeometry(oldGeometry);    oldGeometry = g;    layout->invalidate();    layoutBase->show();    if (qobject_cast<QLayoutWidget*>(layoutBase) || qobject_cast<QSplitter*>(layoutBase)) {        formWindow->manageWidget(layoutBase);        formWindow->selectWidget(layoutBase);    }}void Layout::undoLayout(){    if (!m_widgets.count())        return;    formWindow->selectWidget(layoutBase, false);    QDesignerWidgetFactoryInterface *widgetFactory = formWindow->core()->widgetFactory();    QHashIterator<QWidget *, QRect> it(geometries);    while (it.hasNext()) {        it.next();        if (!it.key())            continue;        QWidget* w = it.key();        QRect rc = it.value();        bool showIt = w->isVisibleTo(formWindow);        QWidget *container = widgetFactory->containerOfWidget(m_parentWidget);        // ### remove widget here        QWidget *parentWidget = w->parentWidget();        QDesignerFormEditorInterface *core = formWindow->core();        QDesignerLayoutDecorationExtension *deco = qt_extension<QDesignerLayoutDecorationExtension*>(core->extensionManager(), parentWidget);        if (deco)            deco->removeWidget(w);        w->setParent(container);        w->setGeometry(rc);        if (showIt)            w->show();    }    LayoutInfo::deleteLayout(formWindow->core(), layoutBase);    if (m_parentWidget != layoutBase && !qobject_cast<QMainWindow*>(layoutBase)) {        formWindow->unmanageWidget(layoutBase);        layoutBase->hide();    } else {        QMainWindow *mw = qobject_cast<QMainWindow*>(formWindow->mainContainer());        if (layoutBase != formWindow->mainContainer() &&                    (!mw || mw->centralWidget() != layoutBase))            layoutBase->setGeometry(oldGeometry);    }    QWidget *ww = m_widgets.size() ? m_widgets.front() : formWindow;    formWindow->selectWidget(ww);}void Layout::breakLayout(){    QMap<QWidget*, QRect> rects;    foreach (QWidget *w, m_widgets) {        rects.insert(w, w->geometry());    }    QPoint layoutBasePos = layoutBase->pos();    QDesignerWidgetDataBaseInterface *widgetDataBase = formWindow->core()->widgetDataBase();    LayoutInfo::deleteLayout(formWindow->core(), layoutBase);    bool needReparent = qobject_cast<QLayoutWidget*>(layoutBase) ||                        qobject_cast<QSplitter*>(layoutBase)     ||                        (!widgetDataBase->isContainer(layoutBase, false) &&                          layoutBase != formWindow->mainContainer());    bool needResize = qobject_cast<QSplitter*>(layoutBase);    bool add = geometries.isEmpty();    QMapIterator<QWidget*, QRect> it(rects);    while (it.hasNext()) {        it.next();        QWidget *w = it.key();        if (needReparent) {            w->setParent(layoutBase->parentWidget(), 0);            w->move(layoutBasePos + it.value().topLeft());            w->show();        }        if (needResize)            w->resize(it.value().size());        if (add)            geometries.insert(w, QRect(w->pos(), w->size()));    }    if (needReparent) {        layoutBase->hide();        m_parentWidget = layoutBase->parentWidget();        formWindow->unmanageWidget(layoutBase);    } else {        m_parentWidget = layoutBase;    }    if (m_widgets.first() && m_widgets.first()->isVisibleTo(formWindow))        formWindow->selectWidget(m_widgets.first());    else        formWindow->selectWidget(formWindow);}HorizontalLayout::HorizontalLayout(const QList<QWidget*> &wl, QWidget *p, QDesignerFormWindowInterface *fw, QWidget *lb, bool splitter)    : Layout(wl, p, fw, lb, splitter){}void HorizontalLayout::sort(){    HorizontalLayoutList l(m_widgets);    l.sort();    m_widgets = l;}void HorizontalLayout::doLayout(){    bool needMove, needReparent;    if (!prepareLayout(needMove, needReparent))        return;    QDesignerWidgetFactoryInterface *widgetFactory = formWindow->core()->widgetFactory();    QHBoxLayout *layout = (QHBoxLayout*) widgetFactory->createLayout(layoutBase, 0, LayoutInfo::HBox);    foreach (QWidget *w, m_widgets) {        if (needReparent && w->parent() != layoutBase) {            w->setParent(layoutBase, 0);            w->move(QPoint(0,0));        }        if (useSplitter) {            QSplitter *splitter = qobject_cast<QSplitter*>(layoutBase);            Q_ASSERT(splitter != 0);            splitter->addWidget(w);        } else {            if (Spacer *spacer = qobject_cast<Spacer*>(w))                layout->addWidget(w, 0, spacer->alignment());            else                add_to_box_layout(layout, w);        }        w->show();    }    if (QSplitter *splitter = qobject_cast<QSplitter*>(layoutBase))        splitter->setOrientation(Qt::Horizontal);    finishLayout(needMove, layout);}VerticalLayout::VerticalLayout(const QList<QWidget*> &wl, QWidget *p, QDesignerFormWindowInterface *fw, QWidget *lb, bool splitter)    : Layout(wl, p, fw, lb, splitter){}void VerticalLayout::sort(){    VerticalLayoutList l(m_widgets);    l.sort();    m_widgets = l;}void VerticalLayout::doLayout(){    bool needMove, needReparent;    if (!prepareLayout(needMove, needReparent))        return;    QDesignerWidgetFactoryInterface *widgetFactory = formWindow->core()->widgetFactory();    QVBoxLayout *layout = (QVBoxLayout*) widgetFactory->createLayout(layoutBase, 0, LayoutInfo::VBox);    Q_ASSERT(layout != 0);    foreach (QWidget *w, m_widgets) {        if (needReparent && w->parent() != layoutBase) {            w->setParent(layoutBase, 0);            w->move(QPoint(0,0));        }        if (useSplitter) {            QSplitter *splitter = qobject_cast<QSplitter*>(layoutBase);            Q_ASSERT(splitter != 0);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -