1 #include "mdiarea.h"
2 #include "mainwindow.h"
3 #include "iconmanager.h"
4 #include "mdichild.h"
5 #include "mdiwindow.h"
6 #include "taskbar.h"
7 #include "uiconfig.h"
8 #include <QMdiSubWindow>
9 #include <QAction>
10 #include <QActionGroup>
11 #include <QDebug>
12 
MdiArea(QWidget * parent)13 MdiArea::MdiArea(QWidget *parent) :
14     QMdiArea(parent)
15 {
16 }
17 
addSubWindow(MdiChild * mdiChild)18 MdiWindow *MdiArea::addSubWindow(MdiChild *mdiChild)
19 {
20     MdiWindow* mdiWin = new MdiWindow(mdiChild, this);
21     QMdiArea::addSubWindow(mdiWin);
22     mdiWin->show();
23 
24     if (taskBar)
25     {
26         QAction* action = taskBar->addTask(mdiWin->windowIcon(), mdiWin->windowTitle());
27         action->setCheckable(true);
28         action->setChecked(true);
29         actionToWinMap[action] = mdiWin;
30         winToActionMap[mdiWin] = action;
31 
32         connect(action, &QAction::triggered, this, &MdiArea::taskActivated);
33         connect(mdiWin, &QMdiSubWindow::aboutToActivate, this, &MdiArea::windowActivated);
34     }
35 
36     if (!mdiChild->handleInitialFocus())
37         mdiChild->setFocus();
38 
39     if (taskBar)
40     {
41         if (taskBar->getTasks().size() == 1 && CFG_UI.General.OpenMaximized.get())
42             mdiWin->setWindowState(mdiWin->windowState()|Qt::WindowMaximized);
43     }
44 
45     emit windowListChanged();
46     return mdiWin;
47 }
48 
getActiveWindow()49 MdiWindow *MdiArea::getActiveWindow()
50 {
51     return dynamic_cast<MdiWindow*>(activeSubWindow());
52 }
53 
setTaskBar(TaskBar * value)54 void MdiArea::setTaskBar(TaskBar* value)
55 {
56     taskBar = value;
57 }
58 
getTaskBar() const59 TaskBar* MdiArea::getTaskBar() const
60 {
61     return taskBar;
62 }
63 
getTaskByWindow(MdiWindow * window)64 QAction* MdiArea::getTaskByWindow(MdiWindow* window)
65 {
66     if (winToActionMap.contains(window))
67         return winToActionMap[window];
68 
69     return nullptr;
70 }
71 
getWindows() const72 QList<MdiWindow*> MdiArea::getWindows() const
73 {
74     QList<MdiWindow*> windowList;
75     for (QAction* action : taskBar->getTasks())
76         windowList << actionToWinMap[action];
77 
78     return windowList;
79 }
80 
getMdiChilds() const81 QList<MdiChild*> MdiArea::getMdiChilds() const
82 {
83     QList<MdiChild*> childs;
84     for (MdiWindow* win : getWindows())
85         childs << win->getMdiChild();
86 
87     return childs;
88 }
89 
getWindowsToTile() const90 QList<MdiWindow*> MdiArea::getWindowsToTile() const
91 {
92     QList<MdiWindow*> list;
93     for (MdiWindow *window : getWindows())
94     {
95         if (window->isMinimized())
96             continue;
97 
98         list << window;
99     }
100     return list;
101 }
102 
taskActivated()103 void MdiArea::taskActivated()
104 {
105     QAction* action = dynamic_cast<QAction*>(sender());
106     if (!action)
107     {
108         qWarning() << "MdiArea::taskActivated() slot called by sender that is not QAction.";
109         return;
110     }
111 
112     setActiveSubWindow(actionToWinMap[action]);
113 }
114 
windowDestroyed(MdiWindow * window)115 void MdiArea::windowDestroyed(MdiWindow* window)
116 {
117     if (!taskBar)
118         return;
119 
120     QAction* action = winToActionMap[window];
121     QAction* taskToSelect = nullptr;
122     if (!MAINWINDOW->isClosingApp())
123     {
124         taskToSelect = taskBar->getNextTask(action);
125         if (!taskToSelect)
126             taskToSelect = taskBar->getPrevTask(action);
127     }
128 
129     winToActionMap.remove(window);
130     actionToWinMap.remove(action);
131     taskBar->removeTask(action);
132     delete action;
133 
134     emit windowListChanged();
135 
136     if (taskToSelect)
137         taskBar->setActiveTask(taskToSelect);
138 }
139 
windowActivated()140 void MdiArea::windowActivated()
141 {
142     if (!taskBar)
143         return;
144 
145     MdiWindow* subWin = dynamic_cast<MdiWindow*>(sender());
146     if (!subWin)
147     {
148         qWarning() << "MdiArea::windowActivated() slot called by sender that is not QMdiSubWindow.";
149         return;
150     }
151 
152     QAction* action = winToActionMap[subWin];
153     action->setChecked(true);
154 }
155 
tileHorizontally()156 void MdiArea::tileHorizontally()
157 {
158     if (taskBar->isEmpty())
159         return;
160 
161     bool gotFocus = false;
162     QPoint position(0, 0);
163     QList<MdiWindow*> windowsToTile = getWindowsToTile();
164     int winCnt = windowsToTile.count();
165     for (MdiWindow *window : windowsToTile)
166     {
167         if (window->isMaximized())
168             window->showNormal();
169 
170         QRect rect(0, 0, width() / winCnt, height());
171         window->setGeometry(rect);
172         window->move(position);
173         position.setX(position.x() + window->width());
174 
175         if (window->hasFocus())
176             gotFocus = true;
177     }
178 
179     if (!gotFocus && windowsToTile.size() > 0)
180         windowsToTile.first()->setFocus();
181 }
182 
tileVertically()183 void MdiArea::tileVertically()
184 {
185     if (taskBar->isEmpty())
186         return;
187 
188     bool gotFocus = false;
189     QPoint position(0, 0);
190     QList<MdiWindow*> windowsToTile = getWindowsToTile();
191     int winCnt = windowsToTile.count();
192     for (MdiWindow *window : windowsToTile)
193     {
194         if (window->isMaximized())
195             window->showNormal();
196 
197         QRect rect(0, 0, width(), height() / winCnt);
198         window->setGeometry(rect);
199         window->move(position);
200         position.setY(position.y() + window->height());
201 
202         if (window->hasFocus())
203             gotFocus = true;
204     }
205 
206     if (!gotFocus && windowsToTile.size() > 0)
207         windowsToTile.first()->setFocus();
208 }
209 
closeAllButActive()210 void MdiArea::closeAllButActive()
211 {
212     QList<QMdiSubWindow*> allButActive = subWindowList();
213     allButActive.removeOne(activeSubWindow());
214 
215     for (QMdiSubWindow *window : allButActive)
216         window->close();
217 }
218 
getWindowByChild(MdiChild * child)219 MdiWindow* MdiArea::getWindowByChild(MdiChild *child)
220 {
221     if (!child)
222         return nullptr;
223 
224     for (QMdiSubWindow *window : subWindowList())
225         if (window->widget() == child)
226             return dynamic_cast<MdiWindow*>(window);
227 
228     return nullptr;
229 }
230 
getCurrentWindow()231 MdiWindow* MdiArea::getCurrentWindow()
232 {
233     QMdiSubWindow* subWin = activeSubWindow();
234     return dynamic_cast<MdiWindow*>(subWin);
235 }
236 
isActiveSubWindow(MdiWindow * window)237 bool MdiArea::isActiveSubWindow(MdiWindow *window)
238 {
239     if (!window)
240         return false;
241 
242     QMdiSubWindow* subWin = currentSubWindow();
243     if (!subWin)
244         return false;
245 
246     return window == subWin;
247 }
248 
isActiveSubWindow(MdiChild * child)249 bool MdiArea::isActiveSubWindow(MdiChild *child)
250 {
251     if (!child)
252         return false;
253 
254     QMdiSubWindow* subWin = currentSubWindow();
255     if (!subWin)
256         return false;
257 
258     return child == subWin->widget();
259 }
260 
getWindowTitles()261 QStringList MdiArea::getWindowTitles()
262 {
263     QStringList titles;
264     for (QMdiSubWindow *subWin : subWindowList())
265         titles << subWin->windowTitle();
266 
267     return titles;
268 }
269 
getWindowByTitle(const QString & title)270 MdiWindow *MdiArea::getWindowByTitle(const QString &title)
271 {
272     for (QMdiSubWindow *subWin : subWindowList())
273     {
274         QString t = subWin->windowTitle();
275         if (subWin->windowTitle() == title)
276         {
277             return dynamic_cast<MdiWindow*>(subWin);
278         }
279     }
280 
281     return nullptr;
282 }
283