Example #1
0
void Q3DockArea::dockWindow(Q3DockWindow *dockWindow, DockWindowData *data)
{
    if (!data)
        return;

    dockWindow->setParent(this);
    dockWindow->move(0, 0);

    dockWindow->installEventFilter(this);
    dockWindow->dockArea = this;
    dockWindow->updateGui();

    if (dockWindows.isEmpty()) {
        dockWindows.append(dockWindow);
    } else {
        QList<Q3DockWindow *> lineStarts = layout->lineStarts();
        int index = 0;
        if (lineStarts.count() > data->line)
            index = dockWindows.indexOf(lineStarts.at(data->line));
        if (index == -1)
            index = 0;
        bool firstTime = true;
        int offset = data->offset;
        for (int i = index; i < dockWindows.size(); ++i) {
            Q3DockWindow *dw = dockWindows.at(i);
            if (!firstTime && lineStarts.contains(dw))
                break;
            if (offset <
                 point_pos(fix_pos(dw), orientation()) + size_extent(dw->size(), orientation()) / 2)
                break;
            index++;
            firstTime = false;
        }
        if (index >= 0 && index < dockWindows.count() &&
             dockWindows.at(index)->newLine() && lineOf(index) == data->line) {
            dockWindows.at(index)->setNewLine(false);
            dockWindow->setNewLine(true);
        } else {
            dockWindow->setNewLine(false);
        }

        dockWindows.insert(index, dockWindow);
    }
    dockWindow->show();

    dockWindow->setFixedExtentWidth(data->fixedExtent.width());
    dockWindow->setFixedExtentHeight(data->fixedExtent.height());

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

}
Example #2
0
void QDockArea::dockWindow( QDockWindow *dockWindow, DockWindowData *data )
{
    if ( !data )
	return;

    dockWindow->reparent( this, QPoint( 0, 0 ), FALSE );
    dockWindow->installEventFilter( this );
    dockWindow->dockArea = this;
    dockWindow->updateGui();

    if ( dockWindows->isEmpty() ) {
	dockWindows->append( dockWindow );
    } else {
	QPtrList<QDockWindow> lineStarts = layout->lineStarts();
	int index = 0;
	if ( (int)lineStarts.count() > data->line )
	    index = dockWindows->find( lineStarts.at( data->line ) );
	if ( index == -1 ) {
	    index = 0;
	    (void)dockWindows->at( index );
	}
	bool firstTime = TRUE;
	int offset = data->offset;
	for ( QDockWindow *dw = dockWindows->current(); dw; dw = dockWindows->next() ) {
	    if ( !firstTime && lineStarts.find( dw ) != -1 )
		break;
	    if ( offset <
		 point_pos( fix_pos( dw ), orientation() ) + size_extent( dw->size(), orientation() ) / 2 )
		break;
	    index++;
	    firstTime = FALSE;
	}
	if ( index >= 0 && index < (int)dockWindows->count() &&
	     dockWindows->at( index )->newLine() && lineOf( index ) == data->line ) {
	    dockWindows->at( index )->setNewLine( FALSE );
	    dockWindow->setNewLine( TRUE );
	} else {
	    dockWindow->setNewLine( FALSE );
	}

	dockWindows->insert( index, dockWindow );
    }
    dockWindow->show();

    dockWindow->setFixedExtentWidth( data->fixedExtent.width() );
    dockWindow->setFixedExtentHeight( data->fixedExtent.height() );

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

}
Example #3
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));
}
Example #4
0
int Q3DockAreaLayout::layoutItems(const QRect &rect, bool testonly)
{
    if (dockWindows->isEmpty())
        return 0;

    dirty = false;

    // some corrections
    QRect r = rect;
    if (orientation() == Qt::Vertical)
        r.setHeight(r.height() - 3);

    // init
    lines.clear();
    ls.clear();
    int start = start_pos(r, orientation());
    int pos = start;
    int sectionpos = 0;
    int linestrut = 0;
    QList<Q3DockData> lastLine;
    int tbstrut = -1;
    int maxsize = size_extent(rect.size(), orientation());
    int visibleWindows = 0;

    // go through all widgets in the dock
    for (int i = 0; i < dockWindows->size(); ++i) {
        Q3DockWindow *dw = dockWindows->at(i);
        if (dw->isHidden())
            continue;
        ++visibleWindows;
        // find position for the widget: This is the maximum of the
        // end of the previous widget and the offset of the widget. If
        // the position + the width of the widget dosn't fit into the
        // dock, try moving it a bit back, if possible.
        int op = pos;
        int dockExtend = dock_extent(dw, orientation(), maxsize);
        if (!dw->isStretchable()) {
            pos = qMax(pos, dw->offset());
            if (pos + dockExtend > size_extent(r.size(), orientation()) - 1)
                pos = qMax(op, size_extent(r.size(), orientation()) - 1 - dockExtend);
        }
        if (!lastLine.isEmpty() && !dw->newLine() && space_left(rect, pos, orientation()) < dockExtend)
            shrink_extend(dw, dockExtend, space_left(rect, pos, orientation()), orientation());
        // if the current widget doesn't fit into the line anymore and it is not the first widget of the line
        if (!lastLine.isEmpty() &&
             (space_left(rect, pos, orientation()) < dockExtend || dw->newLine())) {
            if (!testonly) // place the last line, if not in test mode
                place_line(lastLine, orientation(), linestrut, size_extent(r.size(), orientation()), tbstrut, maxsize, this);
            // remember the line coordinats of the last line
            if (orientation() == Qt::Horizontal)
                lines.append(QRect(0, sectionpos, r.width(), linestrut));
            else
                lines.append(QRect(sectionpos, 0, linestrut, r.height()));
            // do some clearing for the next line
            lastLine.clear();
            sectionpos += linestrut;
            linestrut = 0;
            pos = start;
            tbstrut = -1;
        }

        // remember first widget of a line
        if (lastLine.isEmpty()) {
            ls.append(dw);
            // try to make the best position
            int op = pos;
            if (!dw->isStretchable())
                pos = qMax(pos, dw->offset());
            if (pos + dockExtend > size_extent(r.size(), orientation()) - 1)
                pos = qMax(op, size_extent(r.size(), orientation()) - 1 - dockExtend);
        }
        // do some calculations and add the remember the rect which the docking widget requires for the placing
        QRect dwRect(pos, sectionpos, dockExtend, dock_strut(dw, orientation() ));
        lastLine.append(Q3DockData(dw, dwRect));
        if (qobject_cast<Q3ToolBar*>(dw))
            tbstrut = qMax(tbstrut, dock_strut(dw, orientation()));
        linestrut = qMax(dock_strut(dw, orientation()), linestrut);
        add_size(dockExtend, pos, orientation());
    }

    // if some stuff was not placed/stored yet, do it now
    if (!testonly)
        place_line(lastLine, orientation(), linestrut, size_extent(r.size(), orientation()), tbstrut, maxsize, this);
    if (orientation() == Qt::Horizontal)
        lines.append(QRect(0, sectionpos, r.width(), linestrut));
    else
        lines.append(QRect(sectionpos, 0, linestrut, r.height()));
    if (lines.size() >= 2 && *(--lines.end()) == *(--(--lines.end())))
        lines.removeLast();

    bool hadResizable = false;
    for (int i = 0; i < dockWindows->size(); ++i) {
        Q3DockWindow *dw = dockWindows->at(i);
        if (!dw->isVisibleTo(parentWidget))
            continue;
        hadResizable = hadResizable || dw->isResizeEnabled();
        dw->updateSplitterVisibility(visibleWindows > 1); //!dw->area()->isLastDockWindow(dw));
        if (Q3ToolBar *tb = qobject_cast<Q3ToolBar *>(dw))
            tb->checkForExtension(dw->size());
    }
    return sectionpos + linestrut;
}