14
14
#include <QMdiSubWindow>
16
16
#include <QWindowStateChangeEvent>
19
20
CMDIArea::CMDIArea(BibleTime *parent)
20
: QMdiArea(parent), m_mdiArrangementMode(ArrangementModeManual)
21
: QMdiArea(parent), m_mdiArrangementMode(ArrangementModeManual) {
22
22
Q_ASSERT(parent != 0);
24
24
setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
28
28
this, SLOT(slotSubWindowActivated(QMdiSubWindow*)));
31
static const int moveSize = 30;
31
33
QMdiSubWindow* CMDIArea::addSubWindow(QWidget * widget, Qt::WindowFlags windowFlags) {
32
34
QMdiSubWindow* subWindow = QMdiArea::addSubWindow(widget, windowFlags);
33
35
subWindow->installEventFilter(this);
35
//If we do have a maximized Window, set it to normal so that the new window can be seen
36
if (activeSubWindow() && activeSubWindow()->isMaximized()) {
37
activeSubWindow()->showNormal();
37
// Change Qt QMdiSubWindow Close action to have no shortcut
38
// This makes our closeWindow actions with Ctrl-W work correctly
39
QList<QAction*> actions = subWindow->systemMenu()->actions();
40
for (int i=0; i<actions.count(); i++) {
41
QAction* action = actions.at(i);
42
QString text = action->text();
43
if (text.contains("Close")) {
44
action->setShortcut(QKeySequence());
49
// Manual arrangement mode
50
enableWindowMinMaxFlags(true);
40
51
if (m_mdiArrangementMode == ArrangementModeManual) {
41
subWindow->resize(400, 400); //set the window to be big enough
52
// Note that the window size/maximization may be changed later by a session restore.
53
// If we already have an active window, make the new one simular to it
54
if (activeSubWindow()) {
55
if (activeSubWindow()->isMaximized()) {
56
// Maximize the new window
57
subWindow->showMaximized();
60
// Make new window the same size as the active window and move it slightly.
61
subWindow->resize(activeSubWindow()->size());
62
QRect subWinGeom = activeSubWindow()->geometry();
63
subWinGeom.translate(moveSize, moveSize);
64
// If it goes off screen, move it almost to the top left
65
if ( ! frameRect().contains(subWinGeom)) {
66
subWinGeom.moveTo(moveSize, moveSize);
68
subWindow->setGeometry(subWinGeom);
72
//set the window to be big enough
73
subWindow->resize(400, 400);
42
75
subWindow->raise();
78
// Automatic arrangement modes
79
enableWindowMinMaxFlags(false);
45
80
triggerWindowUpdate();
60
95
QList<QMdiSubWindow*> windows = usableWindowList();
61
if (activeSubWindow() && activeSubWindow()->isMaximized()) {
62
if (activeSubWindow()->size() != this->size()) {
63
activeSubWindow()->resize(this->size());
66
else if (windows.count() == 1) {
67
windows.at(0)->showMaximized();
70
setUpdatesEnabled(false);
71
QMdiSubWindow* active = activeSubWindow();
73
const int widthForEach = width() / windows.count();
75
foreach (QMdiSubWindow *window, windows) {
78
const int preferredWidth = window->minimumWidth() + window->baseSize().width();
79
const int actWidth = qMax(widthForEach, preferredWidth);
81
window->setGeometry(x, 0, actWidth, height());
85
if (active) active->setFocus();
86
setUpdatesEnabled(true);
88
emitWindowCaptionChanged();
96
setUpdatesEnabled(false);
97
QMdiSubWindow* active = activeSubWindow();
99
const int widthForEach = width() / windows.count();
101
foreach (QMdiSubWindow *window, windows) {
102
window->showNormal();
104
const int preferredWidth = window->minimumWidth() + window->baseSize().width();
105
const int actWidth = qMax(widthForEach, preferredWidth);
107
window->setGeometry(x, 0, actWidth, height());
111
if (active) active->setFocus();
112
setUpdatesEnabled(true);
113
emitWindowCaptionChanged();
91
116
void CMDIArea::myTileHorizontal() {
96
121
QList<QMdiSubWindow*> windows = usableWindowList();
98
if (activeSubWindow() && activeSubWindow()->isMaximized()) {
99
if (activeSubWindow()->size() != this->size()) {
100
activeSubWindow()->resize(this->size());
103
else if (windows.count() == 1) {
104
windows.at(0)->showMaximized();
107
setUpdatesEnabled(false);
108
QMdiSubWindow* active = activeSubWindow();
110
const int heightForEach = height() / windows.count();
112
foreach (QMdiSubWindow *window, windows) {
113
window->showNormal();
115
const int preferredHeight = window->minimumHeight() + window->baseSize().height();
116
const int actHeight = qMax(heightForEach, preferredHeight);
118
window->setGeometry( 0, y, width(), actHeight );
121
if (active) active->setFocus();
122
setUpdatesEnabled(true);
122
setUpdatesEnabled(false);
123
QMdiSubWindow* active = activeSubWindow();
125
const int heightForEach = height() / windows.count();
127
foreach (QMdiSubWindow *window, windows) {
128
window->showNormal();
130
const int preferredHeight = window->minimumHeight() + window->baseSize().height();
131
const int actHeight = qMax(heightForEach, preferredHeight);
133
window->setGeometry( 0, y, width(), actHeight );
136
if (active) active->setFocus();
137
setUpdatesEnabled(true);
138
emitWindowCaptionChanged();
141
void CMDIArea::myTile() {
142
if (!updatesEnabled() || !usableWindowList().count() ) {
124
146
emitWindowCaptionChanged();
132
154
QList<QMdiSubWindow*> windows = usableWindowList();
134
if (activeSubWindow() && activeSubWindow()->isMaximized()) {
135
if (activeSubWindow()->size() != this->size()) {
136
activeSubWindow()->resize(this->size());
139
else if (windows.count() == 1) {
156
if (windows.count() == 1) {
140
157
windows.at(0)->showMaximized();
155
172
if (window == active) { //leave out the active window which should be the top window
175
window->showNormal();
158
176
window->raise(); //make it the on-top-of-window-stack window to make sure they're in the right order
159
177
window->setGeometry(x, y, windowWidth, windowHeight);
181
active->showNormal();
163
182
active->setGeometry(x, y, windowWidth, windowHeight);
165
184
active->activateWindow();
182
202
//in subWindowList() when their ChildAdded-Event is triggered
183
203
QList<QMdiSubWindow*> ret;
184
204
foreach(QMdiSubWindow* w, subWindowList()) {
185
if (w->isMinimized() || w->isHidden()) { //not usable for us
205
if (w->isHidden()) { //not usable for us
197
217
emit sigSetToplevelCaption( client->windowTitle().trimmed() );
200
//resize event of the MDI area itself, update layout if necessary
201
220
void CMDIArea::resizeEvent(QResizeEvent* e) {
202
// Do not call QMdiArea::resizeEvent(e), this would mess up our layout
203
// unless we are in manual mode
204
if (updatesEnabled()) triggerWindowUpdate();
205
if (m_mdiArrangementMode == ArrangementModeManual)
206
QMdiArea::resizeEvent(e);
222
Do not call QMdiArea::resizeEvent(e) unless we are in manual arrangement
223
mode, since this would mess up our layout. The manual arrangement mode
224
should be handled exactly as in QMdiArea.
226
if (m_mdiArrangementMode == ArrangementModeManual) {
227
QMdiArea::resizeEvent(e);
229
else if (updatesEnabled()) {
230
triggerWindowUpdate();
209
234
//handle events of the client windows to update layout if necessary
214
239
if (w == 0) return QMdiArea::eventFilter(o, e);
216
241
switch (e->type()) {
217
case QEvent::WindowStateChange:
242
case QEvent::WindowStateChange: {
219
243
Qt::WindowStates newState(w->windowState());
220
244
Qt::WindowStates oldState(((QWindowStateChangeEvent*)e)->oldState());
262
288
case ArrangementModeCascade:
263
289
QTimer::singleShot(0, this, SLOT(myCascade()));
291
case ArrangementModeTile:
292
QTimer::singleShot(0, this, SLOT(myTile()));
300
void CMDIArea::enableWindowMinMaxFlags(bool enable)
302
foreach(QMdiSubWindow* subWindow, subWindowList()) {
303
Qt::WindowFlags flags = subWindow->windowFlags();
305
flags |= Qt::WindowMinimizeButtonHint;
306
flags |= Qt::WindowMaximizeButtonHint;
309
flags &= ~Qt::WindowMinimizeButtonHint;
310
flags &= ~Qt::WindowMaximizeButtonHint;
312
subWindow->setWindowFlags(flags);