summaryrefslogtreecommitdiff
path: root/src/frontend/cmdiarea.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontend/cmdiarea.cpp')
-rw-r--r--src/frontend/cmdiarea.cpp186
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();
+ }
+}
+