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

📄 qmdiarea.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module 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://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************//*!    \class QMdiArea    \brief The QMdiArea widget provides an area in which MDI windows are displayed.    \since 4.3    \ingroup application    \mainclass    QMdiArea functions, essentially, like a window manager for MDI    windows. For instance, it draws the windows it manages on itself    and arranges them in a cascading or tile pattern. QMdiArea is    commonly used as the center widget in a QMainWindow to create MDI    applications, but can also be placed in any layout. The following    code adds an area to a main window:    \quotefromfile snippets/mdiareasnippets.cpp    \skipto /QMainWindow/    \printuntil /setCentralWidget/    Unlike the window managers for top-level windows, all window flags    (Qt::WindowFlags) are supported by QMdiArea as long as the flags    are supported by the current widget style. If a specific flag is    not supported by the style (e.g., the    \l{Qt::}{WindowShadeButtonHint}), you can still shade the window    with showShaded().    Subwindows in QMdiArea are instances of QMdiSubWindow. They    are added to an MDI area with addSubWindow(). It is common to pass    a QWidget, which is set as the internal widget, to this function,    but it is also possible to pass a QMdiSubWindow directly.The class    inherits QWidget, and you can use the same API as with a normal    top-level window when programming. QMdiSubWindow also has behavior    that is specific to MDI windows. See the QMdiSubWindow class    description for more details.    A subwindow becomes active when it gets the keyboard focus, or    when setFocus() is called. The user activates a window by    moving focus in the usual ways. The MDI area emits the subWindowActivated()    signal when the active window changes, and the activeSubWindow()    function returns the active subwindow.    The convenience function subWindowList() returns a list of all    subwindows. This information could be used in a popup menu    containing a list of windows, for example.    \omit        // does this still hold?        This feature is also        available as part of the \l{Window Menu} Solution.    \endomit    QMdiArea provides two built-in layout strategies for    subwindows: cascadeSubWindows() and tileSubWindows(). Both are    slots and are easily connected to menu entries.    \img qmdiarea-arrange.png        \note The default scroll bar property for QMdiArea is Qt::ScrollBarAlwaysOff.        \sa QMdiSubWindow*//*!    \fn QMdiArea::subWindowActivated(QMdiSubWindow *window)    QMdiArea emits this signal after \a window has been activated. When \a    window is 0, QMdiArea has just deactivated its last active window, and    there are no active windows on the workspace.    \sa QMdiArea::activeSubWindow()*//*!    \enum QMdiArea::AreaOption    This enum describes options that customize the behavior of the    QMdiArea.    \value DontMaximizeSubWindowOnActivation When the active subwindow    is maximized, the default behavior is to maximize the next    subwindow that is activated. Set this option if you do not want    this behavior.*//*!    \enum QMdiArea::WindowOrder    Specifies the order in which child windows are returned from    subWindowList(). The cascadeSubWindows() and tileSubWindows()    functions follow this order when arranging the windows.    \value CreationOrder The windows are returned in the order of    their creation    \value StackingOrder The windows are returned in the order in    which they are stacked; the top-most window is    last in the list.*/#include "qmdiarea_p.h"#ifndef QT_NO_MDIAREA#include <QApplication>#include <QStyle>#if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC)#include <QMacStyle>#endif#include <QChildEvent>#include <QResizeEvent>#include <QScrollBar>#include <QtAlgorithms>#include <QMutableListIterator>#include <QPainter>#include <QFontMetrics>#include <QStyleOption>#include <QDesktopWidget>#include <QDebug>#include <private/qmath_p.h>// Asserts in debug mode, gives warning otherwise.static bool sanityCheck(const QMdiSubWindow * const child, const char *where){    if (!child) {        const char error[] = "null pointer";        Q_ASSERT_X(false, where, error);        qWarning("%s:%s", where, error);        return false;    }    return true;}static bool sanityCheck(const QList<QWidget *> &widgets, const int index, const char *where){    if (index < 0 || index >= widgets.size()) {        const char error[] = "index out of range";        Q_ASSERT_X(false, where, error);        qWarning("%s:%s", where, error);        return false;    }    if (!widgets.at(index)) {        const char error[] = "null pointer";        Q_ASSERT_X(false, where, error);        qWarning("%s:%s", where, error);        return false;    }    return true;}static void setIndex(int *index, int candidate, int min, int max, bool isIncreasing){    if (!index)        return;    if (isIncreasing) {        if (candidate > max)            *index = min;        else            *index = candidate;    } else {        if (candidate < min)            *index = max;        else            *index = candidate;    }}static inline bool useScrollBar(const QRect &childrenRect, const QSize &maxViewportSize,                                Qt::Orientation orientation){    if (orientation == Qt::Horizontal)        return  childrenRect.width() > maxViewportSize.width()                || childrenRect.left() < 0                || childrenRect.right() >= maxViewportSize.width();    else        return childrenRect.height() > maxViewportSize.height()               || childrenRect.top() < 0               || childrenRect.bottom() >= maxViewportSize.height();}/*!    \internal*/void RegularTiler::rearrange(QList<QWidget *> &widgets, const QRect &domain) const{    if (widgets.isEmpty())        return;    const int n = widgets.size();    const int ncols = qMax(qCeil(qSqrt(qreal(n))), 1);    const int nrows = qMax((n % ncols) ? (n / ncols + 1) : (n / ncols), 1);    const int nspecial = (n % ncols) ? (ncols - n % ncols) : 0;    const int dx = domain.width()  / ncols;    const int dy = domain.height() / nrows;    int i = 0;    for (int row = 0; row < nrows; ++row) {        const int y1 = int(row * (dy + 1));        for (int col = 0; col < ncols; ++col) {            if (row == 1 && col < nspecial)                continue;            const int x1 = int(col * (dx + 1));            int x2 = int(x1 + dx);            int y2 = int(y1 + dy);            if (row == 0 && col < nspecial) {                y2 *= 2;                if (nrows != 2)                    y2 += 1;                else                    y2 = domain.bottom();            }            if (col == ncols - 1 && x2 != domain.right())                x2 = domain.right();            if (row == nrows - 1 && y2 != domain.bottom())                y2 = domain.bottom();            if (!sanityCheck(widgets, i, "RegularTiler"))                continue;            QWidget *widget = widgets.at(i++);            QRect newGeometry = QRect(QPoint(x1, y1), QPoint(x2, y2));            widget->setGeometry(QStyle::visualRect(widget->layoutDirection(), domain, newGeometry));        }    }}/*!    \internal*/void SimpleCascader::rearrange(QList<QWidget *> &widgets, const QRect &domain) const{    if (widgets.isEmpty())        return;    // Tunables:    const int topOffset = 0;    const int bottomOffset = 50;    const int leftOffset = 0;    const int rightOffset = 100;    const int dx = 10;    QStyleOptionTitleBar options;    options.initFrom(widgets.at(0));    int titleBarHeight = widgets.at(0)->style()->pixelMetric(QStyle::PM_TitleBarHeight, &options);#if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC)    // ### Remove this after the mac style has been fixed    if (qobject_cast<QMacStyle *>(widgets.at(0)->style()))        titleBarHeight -= 4;#endif    const QFontMetrics fontMetrics = QFontMetrics(QApplication::font("QWorkspaceTitleBar"));    const int dy = qMax(titleBarHeight - (titleBarHeight - fontMetrics.height()) / 2, 1);    const int n = widgets.size();    const int nrows = qMax((domain.height() - (topOffset + bottomOffset)) / dy, 1);    const int ncols = qMax(n / nrows + ((n % nrows) ? 1 : 0), 1);    const int dcol = (domain.width() - (leftOffset + rightOffset)) / ncols;    int i = 0;    for (int row = 0; row < nrows; ++row) {        for (int col = 0; col < ncols; ++col) {            const int x = leftOffset + row * dx + col * dcol;            const int y = topOffset + row * dy;            if (!sanityCheck(widgets, i, "SimpleCascader"))                continue;            QWidget *widget = widgets.at(i++);            QRect newGeometry = QRect(QPoint(x, y), widget->sizeHint());            widget->setGeometry(QStyle::visualRect(widget->layoutDirection(), domain, newGeometry));            if (i == n)                return;        }    }}/*!    \internal*/void IconTiler::rearrange(QList<QWidget *> &widgets, const QRect &domain) const{    if (widgets.isEmpty() || !sanityCheck(widgets, 0, "IconTiler"))        return;    const int n = widgets.size();    const int width = widgets.at(0)->width();    const int height = widgets.at(0)->height();    const int ncols = qMax(domain.width() / width, 1);    const int nrows = n / ncols + ((n % ncols) ? 1 : 0);    int i = 0;    for (int row = 0; row < nrows; ++row) {        for (int col = 0; col < ncols; ++col) {            const int x = col * width;            const int y = domain.height() - height - row * height;            if (!sanityCheck(widgets, i, "IconTiler"))                continue;            QWidget *widget = widgets.at(i++);            QPoint newPos(x, y);            QRect newGeometry = QRect(newPos.x(), newPos.y(), widget->width(), widget->height());            widget->setGeometry(QStyle::visualRect(widget->layoutDirection(), domain, newGeometry));            if (i == n)                return;        }    }}/*!    \internal    Calculates the accumulated overlap (intersection area) between 'source' and 'rects'.*/int MinOverlapPlacer::accumulatedOverlap(const QRect &source, const QList<QRect> &rects){    int accOverlap = 0;    foreach (QRect rect, rects) {        QRect intersection = source.intersected(rect);        accOverlap += intersection.width() * intersection.height();    }    return accOverlap;}/*!    \internal    Finds among 'source' the rectangle with the minimum accumulated overlap with the    rectangles in 'rects'.*/QRect MinOverlapPlacer::findMinOverlapRect(const QList<QRect> &source, const QList<QRect> &rects){    int minAccOverlap = -1;    QRect minAccOverlapRect;    foreach (QRect srcRect, source) {        const int accOverlap = accumulatedOverlap(srcRect, rects);        if (accOverlap < minAccOverlap || minAccOverlap == -1) {            minAccOverlap = accOverlap;            minAccOverlapRect = srcRect;        }    }    return minAccOverlapRect;}/*!    \internal    Gets candidates for the final placement.*/void MinOverlapPlacer::getCandidatePlacements(const QSize &size, const QList<QRect> &rects,                                              const QRect &domain,QList<QRect> &candidates){    QSet<int> xset;    QSet<int> yset;    xset << domain.left() << domain.right() - size.width() + 1;    yset << domain.top();    if (domain.bottom() - size.height() + 1 >= 0)        yset << domain.bottom() - size.height() + 1;    foreach (QRect rect, rects) {        xset << rect.right() + 1;        yset << rect.bottom() + 1;    }    QList<int> xlist = xset.values();    qSort(xlist.begin(), xlist.end());    QList<int> ylist = yset.values();    qSort(ylist.begin(), ylist.end());    foreach (int y, ylist)        foreach (int x, xlist)            candidates << QRect(QPoint(x, y), size);}/*!    \internal    Finds all rectangles in 'source' not completely inside 'domain'. The result is stored    in 'result' and also removed from 'source'.*/void MinOverlapPlacer::findNonInsiders(const QRect &domain, QList<QRect> &source,                                       QList<QRect> &result){    QMutableListIterator<QRect> it(source);    while (it.hasNext()) {        const QRect srcRect = it.next();        if (!domain.contains(srcRect)) {            result << srcRect;            it.remove();        }    }}/*!   \internal    Finds all rectangles in 'source' that overlaps 'domain' by the maximum overlap area    between 'domain' and any rectangle in 'source'. The result is stored in 'result'.*/void MinOverlapPlacer::findMaxOverlappers(const QRect &domain, const QList<QRect> &source,                                          QList<QRect> &result){    int maxOverlap = -1;    foreach (QRect srcRect, source) {        QRect intersection = domain.intersected(srcRect);        const int overlap = intersection.width() * intersection.height();        if (overlap >= maxOverlap || maxOverlap == -1) {            if (overlap > maxOverlap) {                maxOverlap = overlap;                result.clear();            }            result << srcRect;        }    }}/*!   \internal    Finds among the rectangles in 'source' the best placement. Here, 'best' means the    placement that overlaps the rectangles in 'rects' as little as possible while at the    same time being as much as possible inside 'domain'.*/QPoint MinOverlapPlacer::findBestPlacement(const QRect &domain, const QList<QRect> &rects,                                           QList<QRect> &source){    QList<QRect> nonInsiders;    findNonInsiders(domain, source, nonInsiders);    if (!source.empty())

⌨️ 快捷键说明

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