18 #include <QKeySequence>
19 #include <QMdiSubWindow>
27 #include <QWindowStateChangeEvent>
28 #include "../util/btassert.h"
29 #include "../util/btconnect.h"
38 return qobject_cast<CDisplayWindow *>(mdiWindow->widget());
46 , m_mdiArrangementMode(ArrangementModeManual)
47 , m_activeWindow(nullptr)
50 setFocusPolicy(Qt::ClickFocus);
52 setDocumentMode(
true);
53 setTabsClosable(
true);
60 setActivationOrder(QMdiArea::ActivationHistoryOrder);
63 setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
64 setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
66 BT_CONNECT(
this, &QMdiArea::subWindowActivated,
67 [
this](QMdiSubWindow* client) {
68 if (subWindowList().isEmpty())
71 if (client ==
nullptr) {
87 QMdiSubWindow *
const subWindow = addSubWindow(displayWindow);
88 subWindow->setWindowIcon(displayWindow->windowIcon());
89 BT_CONNECT(displayWindow, &CDisplayWindow::windowIconChanged,
90 subWindow, &QMdiSubWindow::setWindowIcon);
94 for (
auto *
const action : subWindow->systemMenu()->actions()) {
95 if (action->text().contains(QStringLiteral(
"Close"))) {
107 if (activeSubWindow()) {
108 if (activeSubWindow()->isMaximized()) {
109 subWindow->showMaximized();
112 subWindow->resize(activeSubWindow()->size());
113 QRect subWinGeom = activeSubWindow()->geometry();
114 static const int MOVESIZE = 30;
115 subWinGeom.translate(MOVESIZE, MOVESIZE);
117 if (!frameRect().contains(subWinGeom))
118 subWinGeom.moveTo(MOVESIZE, MOVESIZE);
119 subWindow->setGeometry(subWinGeom);
123 subWindow->resize(400, 400);
138 setViewMode(QMdiArea::SubWindowView);
141 setViewMode(QMdiArea::SubWindowView);
145 setViewMode(QMdiArea::TabbedView);
148 setViewMode(QMdiArea::SubWindowView);
155 if (!updatesEnabled()) {
159 if (windows.isEmpty()) {
162 setViewMode(QMdiArea::SubWindowView);
164 setUpdatesEnabled(
false);
166 QMdiSubWindow *
const active = activeSubWindow();
168 const int widthForEach = width() / windows.count();
170 for (
auto *
const window : windows) {
171 window->showNormal();
173 const int preferredWidth = window->minimumWidth() + window->baseSize().width();
174 const int actWidth = qMax(widthForEach, preferredWidth);
176 window->setGeometry(x, 0, actWidth, height());
180 if (active !=
nullptr) {
184 setUpdatesEnabled(
true);
189 if (!updatesEnabled()) {
193 if (windows.isEmpty()) {
196 setViewMode(QMdiArea::SubWindowView);
198 setUpdatesEnabled(
false);
199 QMdiSubWindow *
const active = activeSubWindow();
201 const int heightForEach = height() / windows.count();
203 for (
auto *
const window : windows) {
204 window->showNormal();
206 const int preferredHeight = window->minimumHeight() + window->baseSize().height();
207 const int actHeight = qMax(heightForEach, preferredHeight);
209 window->setGeometry( 0, y, width(), actHeight );
213 if (active !=
nullptr) {
217 setUpdatesEnabled(
true);
223 if (!updatesEnabled()) {
227 if (windows.isEmpty()) {
230 setViewMode(QMdiArea::SubWindowView);
232 setUpdatesEnabled(
false);
233 QMdiSubWindow *
const active = activeSubWindow();
235 const QRect domain = contentsRect();
236 const int n = windows.size();
237 const int ncols = qMax(qCeil(qSqrt(qreal(n))), 1);
238 const int nrows = qMax((n % ncols) ? (n / ncols + 1) : (n / ncols), 1);
239 const int nspecial = (n % ncols) ? (ncols - n % ncols) : 0;
240 const int dx = domain.width() / ncols;
241 const int dy = domain.height() / nrows;
244 for (
int row = 0; row < nrows; ++row) {
245 const int y1 = int(row * (dy + 1));
246 for (
int col = 0; col < ncols; ++col) {
247 if (row == 1 && col < nspecial)
249 const int x1 = int(col * (dx + 1));
250 int x2 = int(x1 + dx);
251 int y2 = int(y1 + dy);
252 if (row == 0 && col < nspecial) {
257 y2 = domain.bottom();
259 if (col == ncols - 1 && x2 != domain.right())
261 if (row == nrows - 1 && y2 != domain.bottom())
262 y2 = domain.bottom();
263 QWidget *widget = windows.at(i++);
264 QRect newGeometry = QRect(QPoint(x1, y1), QPoint(x2, y2));
265 widget->setGeometry(QStyle::visualRect(widget->layoutDirection(), domain, newGeometry));
269 if (active !=
nullptr) {
273 setUpdatesEnabled(
true);
278 if (!updatesEnabled()) {
282 if (windows.isEmpty()) {
285 setViewMode(QMdiArea::SubWindowView);
287 if (windows.count() == 1) {
288 windows.first()->showMaximized();
291 setUpdatesEnabled(
false);
293 QMdiSubWindow *
const active = activeSubWindow();
295 static const unsigned offsetX = 40;
296 static const unsigned offsetY = 40;
297 const unsigned int windowWidth = width() - (windows.count() - 1) * offsetX;
298 const unsigned int windowHeight = height() - (windows.count() - 1) * offsetY;
302 for (
auto *
const window : windows) {
303 if (window == active) {
306 window->showNormal();
308 window->setGeometry(x, y, windowWidth, windowHeight);
312 active->showNormal();
313 active->setGeometry(x, y, windowWidth, windowHeight);
315 active->activateWindow();
317 setUpdatesEnabled(
true);
324 if (activeSubWindow()) {
336 for (
auto *
const w : subWindowList())
362 QMdiArea::resizeEvent(e);
364 else if (updatesEnabled()) {
372 const QMdiSubWindow *
const w = qobject_cast<QMdiSubWindow*>(o);
376 return QMdiArea::eventFilter(o, e);
379 case QEvent::WindowStateChange: {
380 Qt::WindowStates
const newState(w->windowState());
381 Qt::WindowStates
const oldState(
382 static_cast<QWindowStateChangeEvent *
>(e)->oldState());
391 if ((newState ^ oldState) & Qt::WindowMaximized) {
397 if ((newState ^ oldState) & Qt::WindowMinimized) {
405 case QEvent::WindowTitleChange:
406 if (o == activeSubWindow()) {
414 return QMdiArea::eventFilter(o, e);
418 if (updatesEnabled()) {
440 for (
auto *
const subWindow : subWindowList()) {
441 Qt::WindowFlags flags = subWindow->windowFlags();
443 flags |= (Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
446 flags &= ~(Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
448 subWindow->setWindowFlags(flags);
void findText(bool const backward)
void highlightText(const QString &text, bool caseSensitive)
The base class for all display windows of BibleTime.
BtModelViewReadDisplay * displayWidget() const
@ ArrangementModeTileVertical
@ ArrangementModeTileHorizontal
CMDIArea(BibleTime *parent)
void findTextInActiveWindow(bool const backward)
bool eventFilter(QObject *o, QEvent *e) override
void emitWindowCaptionChanged()
void setMDIArrangementMode(const MDIArrangementMode mode)
void enableWindowMinMaxFlags(bool enable)
void triggerWindowUpdate()
void highlightTextInActiveWindow(const QString &text, bool caseSensitive)
CDisplayWindow * m_activeWindow
void resizeEvent(QResizeEvent *e) override
QList< QMdiSubWindow * > usableWindowList() const
QMdiSubWindow * addDisplayWindow(CDisplayWindow *displayWindow)
void sigSetToplevelCaption(const QString &)
void findNextTextInActiveWindow()
void findPreviousTextInActiveWindow()
MDIArrangementMode m_mdiArrangementMode
CDisplayWindow * getDisplayWindow(const QMdiSubWindow *const mdiWindow)