Example #1
0
void Q3DockArea::removeDockWindow(Q3DockWindow *w, bool makeFloating, bool swap, bool fixNewLines)
{
    w->removeEventFilter(this);
    Q3DockWindow *dockWindow = 0;
    int i = findDockWindow(w);
    if (i == -1)
        return;
    dockWindow = dockWindows.at(i);
    dockWindows.removeAt(i);
    QList<Q3DockWindow *> lineStarts = layout->lineStarts();
    if (fixNewLines && lineStarts.contains(dockWindow) && i < dockWindows.count())
        dockWindows.at(i)->setNewLine(true);
    if (makeFloating) {
        QWidget *p = parentWidget() ? parentWidget() : window();
        dockWindow->setParent(p, Qt::WType_Dialog | Qt::WStyle_Customize | Qt::WStyle_NoBorder | Qt::WStyle_Tool);
        dockWindow->move(0, 0);
    }
    if (swap)
        dockWindow->resize(dockWindow->height(), dockWindow->width());
    updateLayout();
    if (dockWindows.isEmpty())
        setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));
}
Example #2
0
void Q3DockArea::moveDockWindow(Q3DockWindow *w, const QPoint &p, const QRect &r, bool swap)
{
    invalidateFixedSizes();
    int mse = -10;
    bool hasResizable = false;
    for (int i = 0; i < dockWindows.size(); ++i) {
        Q3DockWindow *dw = dockWindows.at(i);
        if (dw->isHidden())
            continue;
        if (dw->isResizeEnabled())
            hasResizable = true;
        if (orientation() != Qt::Horizontal)
            mse = qMax(qMax(dw->fixedExtent().width(), dw->width()), mse);
        else
            mse = qMax(qMax(dw->fixedExtent().height(), dw->height()), mse);
    }
    if (!hasResizable && w->isResizeEnabled()) {
        if (orientation() != Qt::Horizontal)
            mse = qMax(w->fixedExtent().width(), mse);
        else
            mse = qMax(w->fixedExtent().height(), mse);
    }

    Q3DockWindow *dockWindow = 0;
    int dockWindowIndex = findDockWindow(w);
    QList<Q3DockWindow *> lineStarts = layout->lineStarts();
    QList<QRect> lines = layout->lineList();
    bool wasAloneInLine = false;
    QPoint pos = mapFromGlobal(p);
    int line = lineOf(dockWindowIndex);
    QRect lr;
    if (line < lines.size())
        lr = lines.at(line);
    if (dockWindowIndex != -1) {
        if (lineStarts.contains(w)
            && ((dockWindowIndex < dockWindows.count() - 1
                 && lineStarts.contains(dockWindows.at(dockWindowIndex + 1)))
                || dockWindowIndex == dockWindows.count() - 1))
            wasAloneInLine = true;
        dockWindow = dockWindows.takeAt(dockWindowIndex);
        if (!wasAloneInLine) { // only do the pre-layout if the widget isn't the only one in its line
            if (lineStarts.contains(dockWindow) && dockWindowIndex < dockWindows.count())
                dockWindows.at(dockWindowIndex)->setNewLine(true);
            layout->layoutItems(QRect(0, 0, width(), height()), true);
        }
    } else {
        dockWindow = w;
        bool vis = dockWindow->isVisible();
        dockWindow->setParent(this);
        dockWindow->move(0, 0);
        if(vis)
            dockWindow->show();
        if (swap)
            dockWindow->resize(dockWindow->height(), dockWindow->width());
        w->installEventFilter(this);
    }

    lineStarts = layout->lineStarts();
    lines = layout->lineList();

    QRect rect = QRect(mapFromGlobal(r.topLeft()), r.size());
    if (orientation() == Qt::Horizontal && QApplication::reverseLayout()) {
        rect = QRect(width() - rect.x() - rect.width(), rect.y(), rect.width(), rect.height());
        pos.rx() = width() - pos.x();
    }
    dockWindow->setOffset(point_pos(rect.topLeft(), orientation()));
    if (orientation() == Qt::Horizontal) {
        int offs = dockWindow->offset();
        if (width() - offs < dockWindow->minimumWidth())
            dockWindow->setOffset(width() - dockWindow->minimumWidth());
    } else {
        int offs = dockWindow->offset();
        if (height() - offs < dockWindow->minimumHeight())
            dockWindow->setOffset(height() - dockWindow->minimumHeight());
    }

    if (dockWindows.isEmpty()) {
        dockWindows.append(dockWindow);
    } else {
        int dockLine = -1;
        bool insertLine = false;
        int i = 0;
        QRect lineRect;
        // find the line which we touched with the mouse
        for (QList<QRect>::Iterator it = lines.begin(); it != lines.end(); ++it, ++i) {
            if (point_pos(pos, orientation(), true) >= point_pos((*it).topLeft(), orientation(), true) &&
                 point_pos(pos, orientation(), true) <= point_pos((*it).topLeft(), orientation(), true) +
                 size_extent((*it).size(), orientation(), true)) {
                dockLine = i;
                lineRect = *it;
                break;
            }
        }
        if (dockLine == -1) { // outside the dock...
            insertLine = true;
            if (point_pos(pos, orientation(), true) < 0) // insert as first line
                dockLine = 0;
            else
                dockLine = (int)lines.count(); // insert after the last line ### size_t/int cast
        } else { // inside the dock (we have found a dockLine)
            if (point_pos(pos, orientation(), true) <
                 point_pos(lineRect.topLeft(), orientation(), true) + 4) {        // mouse was at the very beginning of the line
                insertLine = true;                                        // insert a new line before that with the docking widget
            } else if (point_pos(pos, orientation(), true) >
                        point_pos(lineRect.topLeft(), orientation(), true) +
                        size_extent(lineRect.size(), orientation(), true) - 4) {        // mouse was at the very and of the line
                insertLine = true;                                                // insert a line after that with the docking widget
                dockLine++;
            }
        }

        if (!insertLine && wasAloneInLine && lr.contains(pos)) // if we are alone in a line and just moved in there, re-insert it
            insertLine = true;

#if defined(QDOCKAREA_DEBUG)
        qDebug("insert in line %d, and insert that line: %d", dockLine, insertLine);
        qDebug("     (btw, we have %d lines)", lines.count());
#endif
        Q3DockWindow *dw = 0;
        if (dockLine >= (int)lines.count()) { // insert after last line
            dockWindows.append(dockWindow);
            dockWindow->setNewLine(true);
#if defined(QDOCKAREA_DEBUG)
            qDebug("insert at the end");
#endif
        } else if (dockLine == 0 && insertLine) { // insert before first line
            dockWindows.insert(0, dockWindow);
            dockWindows.at(1)->setNewLine(true);
#if defined(QDOCKAREA_DEBUG)
            qDebug("insert at the begin");
#endif
        } else { // insert somewhere in between
            // make sure each line start has a new line
            for (int i = 0; i < lineStarts.size(); ++i) {
                dw = lineStarts.at(i);
                dw->setNewLine(true);
            }

            // find the index of the first widget in the search line
            int searchLine = dockLine;
#if defined(QDOCKAREA_DEBUG)
            qDebug("search line start of %d", searchLine);
#endif
            Q3DockWindow *lsw = lineStarts.at(searchLine);
            int index = dockWindows.indexOf(lsw);
            if (index == -1) { // the linestart widget hasn't been found, try to find it harder
                if (lsw == w && dockWindowIndex <= dockWindows.count())
                    index = dockWindowIndex;
                else
                    index = 0;
            }
#if defined(QDOCKAREA_DEBUG)
            qDebug("     which starts at %d", index);
#endif
            if (!insertLine) { // if we insert the docking widget in the existing line
                // find the index for the widget
                bool inc = true;
                bool firstTime = true;
                for (int i = index; i < dockWindows.size(); ++i) {
                    dw = dockWindows.at(i);
                    if (orientation() == Qt::Horizontal)
                        dw->setFixedExtentWidth(-1);
                    else
                        dw->setFixedExtentHeight(-1);
                    if (!firstTime && lineStarts.contains(dw)) // we are in the next line, so break
                        break;
                    if (point_pos(pos, orientation()) <
                         point_pos(fix_pos(dw), orientation()) + size_extent(dw->size(), orientation()) / 2) {
                        inc = false;
                    }
                    if (inc)
                        index++;
                    firstTime = false;
                }
#if defined(QDOCKAREA_DEBUG)
                qDebug("insert at index: %d", index);
#endif
                // if we insert it just before a widget which has a new line, transfer the newline to the docking widget
                // but not if we didn't only mave a widget in its line which was alone in the line before
                if (!(wasAloneInLine && lr.contains(pos))
                     && index >= 0 && index < dockWindows.count() &&
                     dockWindows.at(index)->newLine() && lineOf(index) == dockLine) {
#if defined(QDOCKAREA_DEBUG)
                    qDebug("get rid of the old newline and get me one");
#endif
                    dockWindows.at(index)->setNewLine(false);
                    dockWindow->setNewLine(true);
                } else if (wasAloneInLine && lr.contains(pos)) {
                    dockWindow->setNewLine(true);
                } else { // if we are somewhere in a line, get rid of the newline
                    dockWindow->setNewLine(false);
                }
            } else { // insert in a new line, so make sure the dock widget and the widget which will be after it have a newline
#if defined(QDOCKAREA_DEBUG)
                qDebug("insert a new line");
#endif
                if (index < dockWindows.count()) {
#if defined(QDOCKAREA_DEBUG)
                    qDebug("give the widget at %d a newline", index);
#endif
                    Q3DockWindow* nldw = dockWindows.at(index);
                    if (nldw)
                        nldw->setNewLine(true);
                }
#if defined(QDOCKAREA_DEBUG)
                qDebug("give me a newline");
#endif
                dockWindow->setNewLine(true);
            }
            // finally insert the widget
            dockWindows.insert(index, dockWindow);
        }
    }

    if (mse != -10 && w->isResizeEnabled()) {
        if (orientation() != Qt::Horizontal)
            w->setFixedExtentWidth(qMin(qMax(w->minimumWidth(), mse), w->sizeHint().width()));
        else
            w->setFixedExtentHeight(qMin(qMax(w->minimumHeight(), mse), w->sizeHint().height()));
    }

    updateLayout();
    setSizePolicy(QSizePolicy(orientation() == Qt::Horizontal ? QSizePolicy::Expanding : QSizePolicy::Minimum,
                                orientation() == Qt::Vertical ? QSizePolicy::Expanding : QSizePolicy::Minimum));
}