diff options
Diffstat (limited to 'src/frontend/cmdiarea.cpp')
-rw-r--r-- | src/frontend/cmdiarea.cpp | 186 |
1 files changed, 117 insertions, 69 deletions
diff --git a/src/frontend/cmdiarea.cpp b/src/frontend/cmdiarea.cpp index 3745993..c499962 100644 --- a/src/frontend/cmdiarea.cpp +++ b/src/frontend/cmdiarea.cpp @@ -14,11 +14,11 @@ #include <QMdiSubWindow> #include <QTimer> #include <QWindowStateChangeEvent> +#include <QMenu> CMDIArea::CMDIArea(BibleTime *parent) - : QMdiArea(parent), m_mdiArrangementMode(ArrangementModeManual) -{ + : QMdiArea(parent), m_mdiArrangementMode(ArrangementModeManual) { Q_ASSERT(parent != 0); setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); @@ -28,20 +28,55 @@ CMDIArea::CMDIArea(BibleTime *parent) this, SLOT(slotSubWindowActivated(QMdiSubWindow*))); } +static const int moveSize = 30; + QMdiSubWindow* CMDIArea::addSubWindow(QWidget * widget, Qt::WindowFlags windowFlags) { QMdiSubWindow* subWindow = QMdiArea::addSubWindow(widget, windowFlags); subWindow->installEventFilter(this); - //If we do have a maximized Window, set it to normal so that the new window can be seen - if (activeSubWindow() && activeSubWindow()->isMaximized()) { - activeSubWindow()->showNormal(); + // Change Qt QMdiSubWindow Close action to have no shortcut + // This makes our closeWindow actions with Ctrl-W work correctly + QList<QAction*> actions = subWindow->systemMenu()->actions(); + for (int i=0; i<actions.count(); i++) { + QAction* action = actions.at(i); + QString text = action->text(); + if (text.contains("Close")) { + action->setShortcut(QKeySequence()); + break; + } } + // Manual arrangement mode + enableWindowMinMaxFlags(true); if (m_mdiArrangementMode == ArrangementModeManual) { - subWindow->resize(400, 400); //set the window to be big enough + // Note that the window size/maximization may be changed later by a session restore. + // If we already have an active window, make the new one simular to it + if (activeSubWindow()) { + if (activeSubWindow()->isMaximized()) { + // Maximize the new window + subWindow->showMaximized(); + } + else { + // Make new window the same size as the active window and move it slightly. + subWindow->resize(activeSubWindow()->size()); + QRect subWinGeom = activeSubWindow()->geometry(); + subWinGeom.translate(moveSize, moveSize); + // If it goes off screen, move it almost to the top left + if ( ! frameRect().contains(subWinGeom)) { + subWinGeom.moveTo(moveSize, moveSize); + } + subWindow->setGeometry(subWinGeom); + } + } + else { + //set the window to be big enough + subWindow->resize(400, 400); + } subWindow->raise(); } else { + // Automatic arrangement modes + enableWindowMinMaxFlags(false); triggerWindowUpdate(); } return subWindow; @@ -58,34 +93,24 @@ void CMDIArea::myTileVertical() { } QList<QMdiSubWindow*> windows = usableWindowList(); - if (activeSubWindow() && activeSubWindow()->isMaximized()) { - if (activeSubWindow()->size() != this->size()) { - activeSubWindow()->resize(this->size()); - } - } - else if (windows.count() == 1) { - windows.at(0)->showMaximized(); - } - else { - setUpdatesEnabled(false); - QMdiSubWindow* active = activeSubWindow(); + setUpdatesEnabled(false); + QMdiSubWindow* active = activeSubWindow(); - const int widthForEach = width() / windows.count(); - unsigned int x = 0; - foreach (QMdiSubWindow *window, windows) { - window->showNormal(); + const int widthForEach = width() / windows.count(); + unsigned int x = 0; + foreach (QMdiSubWindow *window, windows) { + window->showNormal(); - const int preferredWidth = window->minimumWidth() + window->baseSize().width(); - const int actWidth = qMax(widthForEach, preferredWidth); + const int preferredWidth = window->minimumWidth() + window->baseSize().width(); + const int actWidth = qMax(widthForEach, preferredWidth); - window->setGeometry(x, 0, actWidth, height()); - x += actWidth; - } - - if (active) active->setFocus(); - setUpdatesEnabled(true); + window->setGeometry(x, 0, actWidth, height()); + x += actWidth; } - emitWindowCaptionChanged(); + + if (active) active->setFocus(); + setUpdatesEnabled(true); +emitWindowCaptionChanged(); } void CMDIArea::myTileHorizontal() { @@ -94,33 +119,30 @@ void CMDIArea::myTileHorizontal() { } QList<QMdiSubWindow*> windows = usableWindowList(); + setUpdatesEnabled(false); + QMdiSubWindow* active = activeSubWindow(); - if (activeSubWindow() && activeSubWindow()->isMaximized()) { - if (activeSubWindow()->size() != this->size()) { - activeSubWindow()->resize(this->size()); - } - } - else if (windows.count() == 1) { - windows.at(0)->showMaximized(); - } - else { - setUpdatesEnabled(false); - QMdiSubWindow* active = activeSubWindow(); + const int heightForEach = height() / windows.count(); + unsigned int y = 0; + foreach (QMdiSubWindow *window, windows) { + window->showNormal(); - const int heightForEach = height() / windows.count(); - unsigned int y = 0; - foreach (QMdiSubWindow *window, windows) { - window->showNormal(); + const int preferredHeight = window->minimumHeight() + window->baseSize().height(); + const int actHeight = qMax(heightForEach, preferredHeight); - const int preferredHeight = window->minimumHeight() + window->baseSize().height(); - const int actHeight = qMax(heightForEach, preferredHeight); + window->setGeometry( 0, y, width(), actHeight ); + y += actHeight; + } + if (active) active->setFocus(); + setUpdatesEnabled(true); + emitWindowCaptionChanged(); +} - window->setGeometry( 0, y, width(), actHeight ); - y += actHeight; - } - if (active) active->setFocus(); - setUpdatesEnabled(true); +void CMDIArea::myTile() { + if (!updatesEnabled() || !usableWindowList().count() ) { + return; } + tileSubWindows(); emitWindowCaptionChanged(); } @@ -131,12 +153,7 @@ void CMDIArea::myCascade() { QList<QMdiSubWindow*> windows = usableWindowList(); - if (activeSubWindow() && activeSubWindow()->isMaximized()) { - if (activeSubWindow()->size() != this->size()) { - activeSubWindow()->resize(this->size()); - } - } - else if (windows.count() == 1) { + if (windows.count() == 1) { windows.at(0)->showMaximized(); } else { @@ -155,11 +172,13 @@ void CMDIArea::myCascade() { if (window == active) { //leave out the active window which should be the top window continue; } + window->showNormal(); window->raise(); //make it the on-top-of-window-stack window to make sure they're in the right order window->setGeometry(x, y, windowWidth, windowHeight); x += offsetX; y += offsetY; } + active->showNormal(); active->setGeometry(x, y, windowWidth, windowHeight); active->raise(); active->activateWindow(); @@ -172,7 +191,8 @@ void CMDIArea::myCascade() { void CMDIArea::emitWindowCaptionChanged() { if (activeSubWindow()) { emit sigSetToplevelCaption(activeSubWindow()->windowTitle()); - } else { + } + else { emit sigSetToplevelCaption(QString()); } } @@ -182,7 +202,7 @@ QList<QMdiSubWindow*> CMDIArea::usableWindowList() { //in subWindowList() when their ChildAdded-Event is triggered QList<QMdiSubWindow*> ret; foreach(QMdiSubWindow* w, subWindowList()) { - if (w->isMinimized() || w->isHidden()) { //not usable for us + if (w->isHidden()) { //not usable for us continue; } ret.append( w ); @@ -197,13 +217,18 @@ void CMDIArea::slotSubWindowActivated(QMdiSubWindow* client) { emit sigSetToplevelCaption( client->windowTitle().trimmed() ); } -//resize event of the MDI area itself, update layout if necessary void CMDIArea::resizeEvent(QResizeEvent* e) { - // Do not call QMdiArea::resizeEvent(e), this would mess up our layout - // unless we are in manual mode - if (updatesEnabled()) triggerWindowUpdate(); - if (m_mdiArrangementMode == ArrangementModeManual) - QMdiArea::resizeEvent(e); + /* + Do not call QMdiArea::resizeEvent(e) unless we are in manual arrangement + mode, since this would mess up our layout. The manual arrangement mode + should be handled exactly as in QMdiArea. + */ + if (m_mdiArrangementMode == ArrangementModeManual) { + QMdiArea::resizeEvent(e); + } + else if (updatesEnabled()) { + triggerWindowUpdate(); + } } //handle events of the client windows to update layout if necessary @@ -214,8 +239,7 @@ bool CMDIArea::eventFilter(QObject *o, QEvent *e) { if (w == 0) return QMdiArea::eventFilter(o, e); switch (e->type()) { - case QEvent::WindowStateChange: - { + case QEvent::WindowStateChange: { Qt::WindowStates newState(w->windowState()); Qt::WindowStates oldState(((QWindowStateChangeEvent*)e)->oldState()); @@ -241,7 +265,9 @@ bool CMDIArea::eventFilter(QObject *o, QEvent *e) { triggerWindowUpdate(); break; case QEvent::WindowTitleChange: - emitWindowCaptionChanged(); + if (o == activeSubWindow()) { + emit sigSetToplevelCaption(w->windowTitle()); + } break; default: break; @@ -262,8 +288,30 @@ void CMDIArea::triggerWindowUpdate() { case ArrangementModeCascade: QTimer::singleShot(0, this, SLOT(myCascade())); break; + case ArrangementModeTile: + QTimer::singleShot(0, this, SLOT(myTile())); + break; default: break; } } } + +void CMDIArea::enableWindowMinMaxFlags(bool enable) +{ + foreach(QMdiSubWindow* subWindow, subWindowList()) { + Qt::WindowFlags flags = subWindow->windowFlags(); + if (enable) { + flags |= Qt::WindowMinimizeButtonHint; + flags |= Qt::WindowMaximizeButtonHint; + } + else { + flags &= ~Qt::WindowMinimizeButtonHint; + flags &= ~Qt::WindowMaximizeButtonHint; + } + subWindow->setWindowFlags(flags); + subWindow->hide(); + subWindow->show(); + } +} + |