📄 q3dockarea.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the Qt3Support 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.******************************************************************************/#include "q3dockarea.h"#ifndef QT_NO_MAINWINDOW#include "qsplitter.h"#include "qevent.h"#include "qlayout.h"#include "qapplication.h"#include "qpainter.h"#include "qmap.h"#include "q3mainwindow.h"#include "q3toolbar.h"//#define QDOCKAREA_DEBUGstruct Q3DockData{ Q3DockData() : w(0), rect() {} Q3DockData(Q3DockWindow *dw, const QRect &r) : w(dw), rect(r) {} Q3DockWindow *w; QRect rect; Q_DUMMY_COMPARISON_OPERATOR(Q3DockData)};static int fix_x(Q3DockWindow* w, int width = -1) { if (QApplication::reverseLayout()) { if (width < 0) width = w->width(); return w->parentWidget()->width() - w->x() - width; } return w->x();}static int fix_x(Q3DockWindow* w, int x, int width = -1) { if (QApplication::reverseLayout()) { if (width < 0) width = w->width(); return w->parentWidget()->width() - x - width; } return x;}static QPoint fix_pos(Q3DockWindow* w) { if (QApplication::reverseLayout()) { QPoint p = w->pos(); p.rx() = w->parentWidget()->width() - p.x() - w->width(); return p; } return w->pos();}void Q3DockAreaLayout::setGeometry(const QRect &r){ QLayout::setGeometry(r); layoutItems(r);}QLayoutItem *Q3DockAreaLayout::itemAt(int) const{ return 0; //###}QLayoutItem *Q3DockAreaLayout::takeAt(int){ return 0; //###}int Q3DockAreaLayout::count() const{ return 0; //###}QSize Q3DockAreaLayout::sizeHint() const{ if (dockWindows->isEmpty()) return QSize(0, 0); if (dirty) { Q3DockAreaLayout *that = (Q3DockAreaLayout *) this; that->layoutItems(geometry()); } int w = 0; int h = 0; int y = -1; int x = -1; int ph = 0; int pw = 0; for (int i = 0; i < dockWindows->size(); ++i) { Q3DockWindow *dw = dockWindows->at(i); int plush = 0, plusw = 0; if (dw->isHidden()) continue; if (hasHeightForWidth()) { if (y != dw->y()) plush = ph; y = dw->y(); ph = dw->height(); } else { if (x != dw->x()) plusw = pw; x = dw->x(); pw = dw->width(); } h = qMax(h, dw->height() + plush); w = qMax(w, dw->width() + plusw); } if (hasHeightForWidth()) return QSize(0, h); return QSize(w, 0);}bool Q3DockAreaLayout::hasHeightForWidth() const{ return orient == Qt::Horizontal;}void Q3DockAreaLayout::init(){ dirty = true; cached_width = 0; cached_height = 0; cached_hfw = -1; cached_wfh = -1;}void Q3DockAreaLayout::invalidate(){ dirty = true; cached_width = 0; cached_height = 0; layoutItems(geometry());}static int start_pos(const QRect &r, Qt::Orientation o){ if (o == Qt::Horizontal) { return qMax(0, r.x()); } else { return qMax(0, r.y()); }}static void add_size(int s, int &pos, Qt::Orientation o){ if (o == Qt::Horizontal) { pos += s; } else { pos += s; }}static int space_left(const QRect &r, int pos, Qt::Orientation o){ if (o == Qt::Horizontal) { return (r.x() + r.width()) - pos; } else { return (r.y() + r.height()) - pos; }}static int dock_extent(Q3DockWindow *w, Qt::Orientation o, int maxsize){ if (o == Qt::Horizontal) return qMin(maxsize, qMax(w->sizeHint().width(), w->fixedExtent().width())); else return qMin(maxsize, qMax(w->sizeHint().height(), w->fixedExtent().height()));}static int dock_strut(Q3DockWindow *w, Qt::Orientation o){ if (o != Qt::Horizontal) { int wid; if ((wid = w->fixedExtent().width()) != -1) return qMax(wid, qMax(w->minimumSize().width(), w->minimumSizeHint().width())); return qMax(w->sizeHint().width(), qMax(w->minimumSize().width(), w->minimumSizeHint().width())); } else { int hei; if ((hei = w->fixedExtent().height()) != -1) return qMax(hei, qMax(w->minimumSizeHint().height(), w->minimumSize().height())); return qMax(w->sizeHint().height(), qMax(w->minimumSizeHint().height(), w->minimumSize().height())); }}static void set_geometry(Q3DockWindow *w, int pos, int sectionpos, int extent, int strut, Qt::Orientation o){ if (o == Qt::Horizontal) w->setGeometry(fix_x(w, pos, extent), sectionpos, extent, strut); else w->setGeometry(sectionpos, pos, strut, extent);}static int size_extent(const QSize &s, Qt::Orientation o, bool swap = false){ return o == Qt::Horizontal ? (swap ? s.height() : s.width()) : (swap ? s.width() : s.height());}static int point_pos(const QPoint &p, Qt::Orientation o, bool swap = false){ return o == Qt::Horizontal ? (swap ? p.y() : p.x()) : (swap ? p.x() : p.y());}static void shrink_extend(Q3DockWindow *dw, int &dockExtend, int /*spaceLeft*/, Qt::Orientation o){ Q3ToolBar *tb = qobject_cast<Q3ToolBar*>(dw); if (o == Qt::Horizontal) { int mw = 0; if (!tb) mw = dw->minimumWidth(); else mw = dw->sizeHint().width(); dockExtend = mw; } else { int mh = 0; if (!tb) mh = dw->minimumHeight(); else mh = dw->sizeHint().height(); dockExtend = mh; }}static void place_line(QList<Q3DockData> &lastLine, Qt::Orientation o, int linestrut, int fullextent, int tbstrut, int maxsize, Q3DockAreaLayout *){ Q3DockWindow *last = 0; QRect lastRect; for (QList<Q3DockData>::Iterator it = lastLine.begin(); it != lastLine.end(); ++it) { if (tbstrut != -1 && qobject_cast<Q3ToolBar*>((*it).w)) (*it).rect.setHeight(tbstrut); if (!last) { last = (*it).w; lastRect = (*it).rect; continue; } if (!last->isStretchable()) { int w = qMin(lastRect.width(), maxsize); set_geometry(last, lastRect.x(), lastRect.y(), w, lastRect.height(), o); } else { int w = qMin((*it).rect.x() - lastRect.x(), maxsize); set_geometry(last, lastRect.x(), lastRect.y(), w, last->isResizeEnabled() ? linestrut : lastRect.height(), o); } last = (*it).w; lastRect = (*it).rect; } if (!last) return; if (!last->isStretchable()) { int w = qMin(lastRect.width(), maxsize); set_geometry(last, lastRect.x(), lastRect.y(), w, lastRect.height(), o); } else { int w = qMin(fullextent - lastRect.x() - (o == Qt::Vertical ? 1 : 0), maxsize); set_geometry(last, lastRect.x(), lastRect.y(), w, last->isResizeEnabled() ? linestrut : lastRect.height(), o); }}QSize Q3DockAreaLayout::minimumSize() const{ if (dockWindows->isEmpty()) return QSize(0, 0); if (dirty) { Q3DockAreaLayout *that = (Q3DockAreaLayout *) this; that->layoutItems(geometry()); } int s = 0; for (int i = 0; i < dockWindows->size(); ++i) { Q3DockWindow *dw = dockWindows->at(i); if (dw->isHidden()) continue; s = qMax(s, dock_strut(dw, orientation())); } return orientation() == Qt::Horizontal ? QSize(0, s ? s+2 : 0) : QSize(s, 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;}int Q3DockAreaLayout::heightForWidth(int w) const{ if (dockWindows->isEmpty() && parentWidget) return parentWidget->minimumHeight(); if (cached_width != w) { Q3DockAreaLayout * mthis = (Q3DockAreaLayout*)this; mthis->cached_width = w; int h = mthis->layoutItems(QRect(0, 0, w, 0), true); mthis->cached_hfw = h; return h; } return cached_hfw;}int Q3DockAreaLayout::widthForHeight(int h) const{ if (cached_height != h) { Q3DockAreaLayout * mthis = (Q3DockAreaLayout*)this; mthis->cached_height = h; int w = mthis->layoutItems(QRect(0, 0, 0, h), true); mthis->cached_wfh = w; return w; } return cached_wfh;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -