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) {
88 for (
auto *
const action : subWindow->systemMenu()->actions()) {
89 if (action->text().contains(QStringLiteral(
"Close"))) {
97 Qt::WindowFlags windowFlags)
99 QMdiSubWindow *
const subWindow = QMdiArea::addSubWindow(widget, windowFlags);
100 subWindow->installEventFilter(
this);
108 if (activeSubWindow()) {
109 if (activeSubWindow()->isMaximized()) {
110 subWindow->showMaximized();
113 subWindow->resize(activeSubWindow()->size());
114 QRect subWinGeom = activeSubWindow()->geometry();
115 static const int MOVESIZE = 30;
116 subWinGeom.translate(MOVESIZE, MOVESIZE);
118 if (!frameRect().contains(subWinGeom))
119 subWinGeom.moveTo(MOVESIZE, MOVESIZE);
120 subWindow->setGeometry(subWinGeom);
124 subWindow->resize(400, 400);
139 setViewMode(QMdiArea::SubWindowView);
142 setViewMode(QMdiArea::SubWindowView);
146 setViewMode(QMdiArea::TabbedView);
149 setViewMode(QMdiArea::SubWindowView);
156 QMdiSubWindow *sub = subWindowList()[i];
159 setActiveSubWindow(sub);
160 closeActiveSubWindow();
164 if (!updatesEnabled()) {
168 if (windows.isEmpty()) {
171 setViewMode(QMdiArea::SubWindowView);
173 setUpdatesEnabled(
false);
175 QMdiSubWindow *
const active = activeSubWindow();
177 const int widthForEach = width() / windows.count();
179 for (
auto *
const window : windows) {
180 window->showNormal();
182 const int preferredWidth = window->minimumWidth() + window->baseSize().width();
183 const int actWidth = qMax(widthForEach, preferredWidth);
185 window->setGeometry(x, 0, actWidth, height());
189 if (active !=
nullptr) {
193 setUpdatesEnabled(
true);
198 if (!updatesEnabled()) {
202 if (windows.isEmpty()) {
205 setViewMode(QMdiArea::SubWindowView);
207 setUpdatesEnabled(
false);
208 QMdiSubWindow *
const active = activeSubWindow();
210 const int heightForEach = height() / windows.count();
212 for (
auto *
const window : windows) {
213 window->showNormal();
215 const int preferredHeight = window->minimumHeight() + window->baseSize().height();
216 const int actHeight = qMax(heightForEach, preferredHeight);
218 window->setGeometry( 0, y, width(), actHeight );
222 if (active !=
nullptr) {
226 setUpdatesEnabled(
true);
232 if (!updatesEnabled()) {
236 if (windows.isEmpty()) {
239 setViewMode(QMdiArea::SubWindowView);
241 setUpdatesEnabled(
false);
242 QMdiSubWindow *
const active = activeSubWindow();
244 const QRect domain = contentsRect();
245 const int n = windows.size();
246 const int ncols = qMax(qCeil(qSqrt(qreal(n))), 1);
247 const int nrows = qMax((n % ncols) ? (n / ncols + 1) : (n / ncols), 1);
248 const int nspecial = (n % ncols) ? (ncols - n % ncols) : 0;
249 const int dx = domain.width() / ncols;
250 const int dy = domain.height() / nrows;
253 for (
int row = 0; row < nrows; ++row) {
254 const int y1 = int(row * (dy + 1));
255 for (
int col = 0; col < ncols; ++col) {
256 if (row == 1 && col < nspecial)
258 const int x1 = int(col * (dx + 1));
259 int x2 = int(x1 + dx);
260 int y2 = int(y1 + dy);
261 if (row == 0 && col < nspecial) {
266 y2 = domain.bottom();
268 if (col == ncols - 1 && x2 != domain.right())
270 if (row == nrows - 1 && y2 != domain.bottom())
271 y2 = domain.bottom();
272 QWidget *widget = windows.at(i++);
273 QRect newGeometry = QRect(QPoint(x1, y1), QPoint(x2, y2));
274 widget->setGeometry(QStyle::visualRect(widget->layoutDirection(), domain, newGeometry));
278 if (active !=
nullptr) {
282 setUpdatesEnabled(
true);
287 if (!updatesEnabled()) {
291 if (windows.isEmpty()) {
294 setViewMode(QMdiArea::SubWindowView);
296 if (windows.count() == 1) {
297 windows.first()->showMaximized();
300 setUpdatesEnabled(
false);
302 QMdiSubWindow *
const active = activeSubWindow();
304 static const unsigned offsetX = 40;
305 static const unsigned offsetY = 40;
306 const unsigned int windowWidth = width() - (windows.count() - 1) * offsetX;
307 const unsigned int windowHeight = height() - (windows.count() - 1) * offsetY;
311 for (
auto *
const window : windows) {
312 if (window == active) {
315 window->showNormal();
317 window->setGeometry(x, y, windowWidth, windowHeight);
321 active->showNormal();
322 active->setGeometry(x, y, windowWidth, windowHeight);
324 active->activateWindow();
326 setUpdatesEnabled(
true);
333 if (activeSubWindow()) {
345 for (
auto *
const w : subWindowList())
371 QMdiArea::resizeEvent(e);
373 else if (updatesEnabled()) {
381 const QMdiSubWindow *
const w = qobject_cast<QMdiSubWindow*>(o);
385 return QMdiArea::eventFilter(o, e);
388 case QEvent::WindowStateChange: {
389 Qt::WindowStates
const newState(w->windowState());
390 Qt::WindowStates
const oldState(
391 static_cast<QWindowStateChangeEvent *
>(e)->oldState());
400 if ((newState ^ oldState) & Qt::WindowMaximized) {
406 if ((newState ^ oldState) & Qt::WindowMinimized) {
414 case QEvent::WindowTitleChange:
415 if (o == activeSubWindow()) {
418 return QMdiArea::eventFilter(o, e);
428 if (updatesEnabled()) {
450 for (
auto *
const subWindow : subWindowList()) {
451 Qt::WindowFlags flags = subWindow->windowFlags();
453 flags |= (Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
456 flags &= ~(Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
458 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)
void fixSystemMenu(QMdiSubWindow *subWindow)
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
void sigSetToplevelCaption(const QString &)
void findNextTextInActiveWindow()
void findPreviousTextInActiveWindow()
MDIArrangementMode m_mdiArrangementMode
QMdiSubWindow * addSubWindow(QWidget *widget, Qt::WindowFlags windowFlags=Qt::WindowFlags())
CDisplayWindow * getDisplayWindow(const QMdiSubWindow *const mdiWindow)