1 /**************************************************************************
2 * Otter Browser: Web browser controlled by the user, not vice-versa.
3 * Copyright (C) 2013 - 2018 Michal Dutkiewicz aka Emdek <michal@emdek.pl>
4 * Copyright (C) 2015 Piotr Wójcik <chocimier@tlen.pl>
5 * Copyright (C) 2016 - 2017 Jan Bajer aka bajasoft <jbajer@gmail.com>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 **************************************************************************/
21
22 #include "Window.h"
23 #include "MainWindow.h"
24 #include "WidgetFactory.h"
25 #include "../core/Application.h"
26 #include "../core/HistoryManager.h"
27 #include "../core/SettingsManager.h"
28 #include "../core/Utils.h"
29 #include "../modules/widgets/address/AddressWidget.h"
30 #include "../modules/widgets/search/SearchWidget.h"
31 #include "../modules/windows/web/WebContentsWidget.h"
32
33 #include <QtCore/QTimer>
34 #include <QtGui/QPainter>
35 #include <QtWidgets/QBoxLayout>
36 #include <QtWidgets/QMdiSubWindow>
37
38 namespace Otter
39 {
40
41 quint64 Window::m_identifierCounter(0);
42
WindowToolBarWidget(int identifier,Window * parent)43 WindowToolBarWidget::WindowToolBarWidget(int identifier, Window *parent) : ToolBarWidget(identifier, parent, parent)
44 {
45 }
46
paintEvent(QPaintEvent * event)47 void WindowToolBarWidget::paintEvent(QPaintEvent *event)
48 {
49 Q_UNUSED(event)
50
51 QPainter painter(this);
52 QStyleOptionToolBar toolBarOption;
53 toolBarOption.initFrom(this);
54 toolBarOption.lineWidth = style()->pixelMetric(QStyle::PM_ToolBarFrameWidth, nullptr, this);
55 toolBarOption.positionOfLine = QStyleOptionToolBar::End;
56 toolBarOption.positionWithinLine = QStyleOptionToolBar::OnlyOne;
57 toolBarOption.state |= QStyle::State_Horizontal;
58 toolBarOption.toolBarArea = Qt::TopToolBarArea;
59
60 style()->drawControl(QStyle::CE_ToolBar, &toolBarOption, &painter, this);
61 }
62
Window(const QVariantMap & parameters,ContentsWidget * widget,MainWindow * mainWindow)63 Window::Window(const QVariantMap ¶meters, ContentsWidget *widget, MainWindow *mainWindow) : QWidget(mainWindow->centralWidget()), ActionExecutor(),
64 m_mainWindow(mainWindow),
65 m_addressBarWidget(nullptr),
66 m_contentsWidget(nullptr),
67 m_parameters(parameters),
68 m_identifier(++m_identifierCounter),
69 m_suspendTimer(0),
70 m_isAboutToClose(false),
71 m_isPinned(false)
72 {
73 QBoxLayout *layout(new QBoxLayout(QBoxLayout::TopToBottom, this));
74 layout->setContentsMargins(0, 0, 0, 0);
75 layout->setSpacing(0);
76
77 setLayout(layout);
78
79 if (widget)
80 {
81 setContentsWidget(widget);
82 }
83
84 connect(this, &Window::titleChanged, this, &Window::setWindowTitle);
85 connect(this, &Window::iconChanged, this, &Window::handleIconChanged);
86 connect(mainWindow, &MainWindow::toolBarStateChanged, this, &Window::handleToolBarStateChanged);
87 }
88
timerEvent(QTimerEvent * event)89 void Window::timerEvent(QTimerEvent *event)
90 {
91 if (event->timerId() == m_suspendTimer)
92 {
93 killTimer(m_suspendTimer);
94
95 m_suspendTimer = 0;
96
97 triggerAction(ActionsManager::SuspendTabAction);
98 }
99 }
100
hideEvent(QHideEvent * event)101 void Window::hideEvent(QHideEvent *event)
102 {
103 QWidget::hideEvent(event);
104
105 const int suspendTime(SettingsManager::getOption(SettingsManager::Browser_InactiveTabTimeUntilSuspendOption).toInt());
106
107 if (m_suspendTimer == 0 && suspendTime >= 0)
108 {
109 m_suspendTimer = startTimer(suspendTime * 1000);
110 }
111 }
112
focusInEvent(QFocusEvent * event)113 void Window::focusInEvent(QFocusEvent *event)
114 {
115 QWidget::focusInEvent(event);
116
117 if (m_suspendTimer != 0)
118 {
119 killTimer(m_suspendTimer);
120
121 m_suspendTimer = 0;
122 }
123
124 updateFocus();
125 }
126
triggerAction(int identifier,const QVariantMap & parameters,ActionsManager::TriggerType trigger)127 void Window::triggerAction(int identifier, const QVariantMap ¶meters, ActionsManager::TriggerType trigger)
128 {
129 switch (identifier)
130 {
131 case ActionsManager::CloneTabAction:
132 if (canClone())
133 {
134 m_mainWindow->addWindow(clone(true, m_mainWindow));
135 }
136
137 break;
138 case ActionsManager::PinTabAction:
139 setPinned(!isPinned());
140
141 break;
142 case ActionsManager::DetachTabAction:
143 if (m_mainWindow->getWindowCount() > 1 || parameters.value(QLatin1String("minimalInterface")).toBool())
144 {
145 m_mainWindow->moveWindow(this, nullptr, parameters);
146 }
147
148 break;
149 case ActionsManager::MaximizeTabAction:
150 case ActionsManager::MinimizeTabAction:
151 case ActionsManager::RestoreTabAction:
152 case ActionsManager::AlwaysOnTopTabAction:
153 {
154 QVariantMap mutableParameters(parameters);
155 mutableParameters[QLatin1String("tab")] = m_identifier;
156
157 m_mainWindow->triggerAction(identifier, mutableParameters, trigger);
158 }
159
160 break;
161 case ActionsManager::SuspendTabAction:
162 if (!m_contentsWidget || m_contentsWidget->close())
163 {
164 m_session = getSession();
165
166 setContentsWidget(nullptr);
167 }
168
169 break;
170 case ActionsManager::CloseTabAction:
171 if (!isPinned())
172 {
173 requestClose();
174 }
175
176 break;
177 case ActionsManager::FullScreenAction:
178 if (m_contentsWidget)
179 {
180 m_contentsWidget->triggerAction(identifier, parameters, trigger);
181 }
182
183 break;
184 default:
185 getContentsWidget()->triggerAction(identifier, parameters, trigger);
186
187 break;
188 }
189 }
190
clear()191 void Window::clear()
192 {
193 if (!m_contentsWidget || m_contentsWidget->close())
194 {
195 setContentsWidget(new WebContentsWidget(m_parameters, {}, nullptr, this, this));
196
197 m_isAboutToClose = false;
198
199 emit urlChanged(getUrl(), true);
200 }
201 }
202
requestClose()203 void Window::requestClose()
204 {
205 if (!m_contentsWidget || m_contentsWidget->close())
206 {
207 m_isAboutToClose = true;
208
209 emit aboutToClose();
210
211 QTimer::singleShot(50, this, [&]()
212 {
213 emit requestedCloseWindow(this);
214 });
215 }
216 }
217
search(const QString & query,const QString & searchEngine)218 void Window::search(const QString &query, const QString &searchEngine)
219 {
220 WebContentsWidget *widget(qobject_cast<WebContentsWidget*>(m_contentsWidget));
221
222 if (!widget)
223 {
224 if (m_contentsWidget && !m_contentsWidget->close())
225 {
226 return;
227 }
228
229 QVariantMap parameters;
230
231 if (isPrivate())
232 {
233 parameters[QLatin1String("hints")] = SessionsManager::PrivateOpen;
234 }
235
236 widget = new WebContentsWidget(parameters, {}, nullptr, this, this);
237
238 setContentsWidget(widget);
239 }
240
241 widget->search(query, searchEngine);
242
243 emit urlChanged(getUrl(), true);
244 }
245
markAsActive(bool updateLastActivity)246 void Window::markAsActive(bool updateLastActivity)
247 {
248 if (m_suspendTimer != 0)
249 {
250 killTimer(m_suspendTimer);
251
252 m_suspendTimer = 0;
253 }
254
255 if (!m_contentsWidget)
256 {
257 setUrl(m_session.getUrl(), false);
258 }
259
260 if (updateLastActivity)
261 {
262 m_lastActivity = QDateTime::currentDateTime();
263 }
264
265 emit activated();
266 }
267
handleIconChanged(const QIcon & icon)268 void Window::handleIconChanged(const QIcon &icon)
269 {
270 QMdiSubWindow *subWindow(qobject_cast<QMdiSubWindow*>(parentWidget()));
271
272 if (subWindow)
273 {
274 subWindow->setWindowIcon(icon);
275 }
276 }
277
handleSearchRequest(const QString & query,const QString & searchEngine,SessionsManager::OpenHints hints)278 void Window::handleSearchRequest(const QString &query, const QString &searchEngine, SessionsManager::OpenHints hints)
279 {
280 if ((getType() == QLatin1String("web") && Utils::isUrlEmpty(getUrl())) || (hints == SessionsManager::DefaultOpen || hints == SessionsManager::CurrentTabOpen))
281 {
282 search(query, searchEngine);
283 }
284 else
285 {
286 emit requestedSearch(query, searchEngine, hints);
287 }
288 }
289
handleGeometryChangeRequest(const QRect & geometry)290 void Window::handleGeometryChangeRequest(const QRect &geometry)
291 {
292 QMdiSubWindow *subWindow(qobject_cast<QMdiSubWindow*>(parentWidget()));
293
294 if (subWindow)
295 {
296 Application::triggerAction(ActionsManager::RestoreTabAction, {{QLatin1String("tab"), getIdentifier()}}, m_mainWindow);
297
298 subWindow->setWindowFlags(Qt::SubWindow);
299 subWindow->showNormal();
300 subWindow->resize(geometry.size() + (subWindow->geometry().size() - m_contentsWidget->size()));
301 subWindow->move(geometry.topLeft());
302 }
303 }
304
handleToolBarStateChanged(int identifier,const ToolBarState & state)305 void Window::handleToolBarStateChanged(int identifier, const ToolBarState &state)
306 {
307 if (m_addressBarWidget && identifier == ToolBarsManager::AddressBar)
308 {
309 m_addressBarWidget->setState(state);
310 }
311 }
312
updateFocus()313 void Window::updateFocus()
314 {
315 QTimer::singleShot(100, this, [&]()
316 {
317 AddressWidget *addressWidget(m_mainWindow->findAddressField());
318
319 if (addressWidget && Utils::isUrlEmpty(getUrl()) && (!m_contentsWidget || m_contentsWidget->getLoadingState() != WebWidget::OngoingLoadingState))
320 {
321 addressWidget->setFocus();
322 }
323 else if (m_contentsWidget)
324 {
325 m_contentsWidget->setFocus();
326 }
327 });
328 }
329
setSession(const SessionWindow & session,bool deferLoading)330 void Window::setSession(const SessionWindow &session, bool deferLoading)
331 {
332 m_session = session;
333
334 setPinned(session.isPinned);
335
336 if (deferLoading)
337 {
338 setWindowTitle(session.getTitle());
339 }
340 else
341 {
342 setUrl(session.getUrl(), false);
343 }
344 }
345
setOption(int identifier,const QVariant & value)346 void Window::setOption(int identifier, const QVariant &value)
347 {
348 if (m_contentsWidget)
349 {
350 m_contentsWidget->setOption(identifier, value);
351 }
352 else if (value != m_session.options.value(identifier))
353 {
354 if (value.isNull())
355 {
356 m_session.options.remove(identifier);
357 }
358 else
359 {
360 m_session.options[identifier] = value;
361 }
362
363 SessionsManager::markSessionAsModified();
364
365 emit optionChanged(identifier, value);
366 }
367 }
368
setUrl(const QUrl & url,bool isTyped)369 void Window::setUrl(const QUrl &url, bool isTyped)
370 {
371 ContentsWidget *newWidget(nullptr);
372
373 if (url.scheme() == QLatin1String("about") || url.scheme() == QLatin1String("view-feed"))
374 {
375 if (m_session.historyIndex < 0 && !Utils::isUrlEmpty(getUrl()) && SessionsManager::hasUrl(url, true))
376 {
377 emit urlChanged(url, true);
378
379 return;
380 }
381
382 newWidget = WidgetFactory::createContentsWidget(((url.scheme() == QLatin1String("view-feed")) ? QLatin1String("feeds") : url.path()), {}, this, this);
383
384 if (newWidget)
385 {
386 newWidget->setUrl(url);
387
388 if (!newWidget->canClone())
389 {
390 SessionsManager::removeStoredUrl(newWidget->getUrl().toString());
391 }
392 }
393 }
394
395 const bool isRestoring(!m_contentsWidget && m_session.historyIndex >= 0);
396
397 if (!newWidget && (!m_contentsWidget || m_contentsWidget->getType() != QLatin1String("web")))
398 {
399 newWidget = new WebContentsWidget(m_parameters, m_session.options, nullptr, this, this);
400 }
401
402 if (newWidget)
403 {
404 if (m_contentsWidget && !m_contentsWidget->close())
405 {
406 return;
407 }
408
409 setContentsWidget(newWidget);
410 }
411
412 if (m_contentsWidget && url.isValid())
413 {
414 if (!isRestoring)
415 {
416 m_contentsWidget->setUrl(url, isTyped);
417 }
418
419 if (!Utils::isUrlEmpty(getUrl()) || m_contentsWidget->getLoadingState() == WebWidget::OngoingLoadingState)
420 {
421 emit urlChanged(url, true);
422 }
423 }
424 }
425
setZoom(int zoom)426 void Window::setZoom(int zoom)
427 {
428 if (m_contentsWidget)
429 {
430 m_contentsWidget->setZoom(zoom);
431 }
432 else if (m_session.historyIndex >= 0 && m_session.historyIndex < m_session.history.count())
433 {
434 m_session.history[m_session.historyIndex].zoom = zoom;
435 }
436 }
437
setPinned(bool isPinned)438 void Window::setPinned(bool isPinned)
439 {
440 if (isPinned != m_isPinned)
441 {
442 m_isPinned = isPinned;
443
444 emit arbitraryActionsStateChanged({ActionsManager::PinTabAction, ActionsManager::CloseTabAction});
445 emit isPinnedChanged(isPinned);
446 }
447 }
448
setContentsWidget(ContentsWidget * widget)449 void Window::setContentsWidget(ContentsWidget *widget)
450 {
451 if (m_contentsWidget)
452 {
453 layout()->removeWidget(m_contentsWidget);
454
455 m_contentsWidget->deleteLater();
456 }
457
458 m_contentsWidget = widget;
459
460 if (!m_contentsWidget)
461 {
462 if (m_addressBarWidget)
463 {
464 layout()->removeWidget(m_addressBarWidget);
465
466 m_addressBarWidget->deleteLater();
467 m_addressBarWidget = nullptr;
468 }
469
470 emit actionsStateChanged();
471
472 return;
473 }
474
475 m_contentsWidget->setParent(this);
476
477 if (!m_addressBarWidget)
478 {
479 m_addressBarWidget = new WindowToolBarWidget(ToolBarsManager::AddressBar, this);
480 m_addressBarWidget->setState(m_mainWindow->getToolBarState(ToolBarsManager::AddressBar));
481
482 layout()->addWidget(m_addressBarWidget);
483 layout()->setAlignment(m_addressBarWidget, Qt::AlignTop);
484 }
485
486 layout()->addWidget(m_contentsWidget);
487
488 if (m_session.historyIndex >= 0 || !m_contentsWidget->getWebWidget() || m_contentsWidget->getWebWidget()->getRequestedUrl().isEmpty())
489 {
490 WindowHistoryInformation history;
491
492 if (m_session.historyIndex >= 0)
493 {
494 history.index = m_session.historyIndex;
495 history.entries = m_session.history;
496 }
497
498 m_contentsWidget->setHistory(history);
499 m_contentsWidget->setZoom(m_session.getZoom());
500 }
501
502 if (isActive())
503 {
504 if (m_session.historyIndex >= 0)
505 {
506 m_contentsWidget->setFocus();
507 }
508 else
509 {
510 const AddressWidget *addressWidget(m_mainWindow->findAddressField());
511
512 if (addressWidget && Utils::isUrlEmpty(m_contentsWidget->getUrl()))
513 {
514 QTimer::singleShot(100, addressWidget, static_cast<void(AddressWidget::*)()>(&AddressWidget::setFocus));
515 }
516 }
517 }
518
519 updateFocus();
520
521 m_session = SessionWindow();
522
523 emit titleChanged(m_contentsWidget->getTitle());
524 emit urlChanged(m_contentsWidget->getUrl(), false);
525 emit iconChanged(m_contentsWidget->getIcon());
526 emit actionsStateChanged();
527 emit loadingStateChanged(m_contentsWidget->getLoadingState());
528 emit canZoomChanged(m_contentsWidget->canZoom());
529
530 connect(m_contentsWidget, &ContentsWidget::aboutToNavigate, this, &Window::aboutToNavigate);
531 connect(m_contentsWidget, &ContentsWidget::needsAttention, this, &Window::needsAttention);
532 connect(m_contentsWidget, &ContentsWidget::requestedNewWindow, this, &Window::requestedNewWindow);
533 connect(m_contentsWidget, &ContentsWidget::requestedSearch, this, &Window::requestedSearch);
534 connect(m_contentsWidget, &ContentsWidget::requestedGeometryChange, this, &Window::handleGeometryChangeRequest);
535 connect(m_contentsWidget, &ContentsWidget::statusMessageChanged, this, &Window::statusMessageChanged);
536 connect(m_contentsWidget, &ContentsWidget::titleChanged, this, &Window::titleChanged);
537 connect(m_contentsWidget, &ContentsWidget::urlChanged, this, [&](const QUrl &url)
538 {
539 emit urlChanged(url, false);
540 });
541 connect(m_contentsWidget, &ContentsWidget::iconChanged, this, &Window::iconChanged);
542 connect(m_contentsWidget, &ContentsWidget::requestBlocked, this, &Window::requestBlocked);
543 connect(m_contentsWidget, &ContentsWidget::arbitraryActionsStateChanged, this, &Window::arbitraryActionsStateChanged);
544 connect(m_contentsWidget, &ContentsWidget::categorizedActionsStateChanged, this, &Window::categorizedActionsStateChanged);
545 connect(m_contentsWidget, &ContentsWidget::contentStateChanged, this, &Window::contentStateChanged);
546 connect(m_contentsWidget, &ContentsWidget::loadingStateChanged, this, &Window::loadingStateChanged);
547 connect(m_contentsWidget, &ContentsWidget::pageInformationChanged, this, &Window::pageInformationChanged);
548 connect(m_contentsWidget, &ContentsWidget::optionChanged, this, &Window::optionChanged);
549 connect(m_contentsWidget, &ContentsWidget::zoomChanged, this, &Window::zoomChanged);
550 connect(m_contentsWidget, &ContentsWidget::canZoomChanged, this, &Window::canZoomChanged);
551 connect(m_contentsWidget, &ContentsWidget::webWidgetChanged, m_addressBarWidget, &WindowToolBarWidget::reload);
552 }
553
clone(bool cloneHistory,MainWindow * mainWindow) const554 Window* Window::clone(bool cloneHistory, MainWindow *mainWindow) const
555 {
556 if (!m_contentsWidget || !canClone())
557 {
558 return nullptr;
559 }
560
561 QVariantMap parameters({{QLatin1String("size"), size()}});
562
563 if (isPrivate())
564 {
565 parameters[QLatin1String("hints")] = SessionsManager::PrivateOpen;
566 }
567
568 return new Window(parameters, m_contentsWidget->clone(cloneHistory), mainWindow);
569 }
570
getMainWindow() const571 MainWindow* Window::getMainWindow() const
572 {
573 return m_mainWindow;
574 }
575
getAddressBar() const576 WindowToolBarWidget* Window::getAddressBar() const
577 {
578 return m_addressBarWidget;
579 }
580
getContentsWidget()581 ContentsWidget* Window::getContentsWidget()
582 {
583 if (!m_contentsWidget)
584 {
585 setUrl(m_session.getUrl(), false);
586 }
587
588 return m_contentsWidget;
589 }
590
getWebWidget()591 WebWidget* Window::getWebWidget()
592 {
593 if (!m_contentsWidget)
594 {
595 setUrl(m_session.getUrl(), false);
596 }
597
598 return m_contentsWidget->getWebWidget();
599 }
600
getTitle() const601 QString Window::getTitle() const
602 {
603 return ((m_contentsWidget && !m_isAboutToClose) ? m_contentsWidget->getTitle() : m_session.getTitle());
604 }
605
getType() const606 QLatin1String Window::getType() const
607 {
608 return ((m_contentsWidget && !m_isAboutToClose) ? m_contentsWidget->getType() : QLatin1String("unknown"));
609 }
610
getOption(int identifier) const611 QVariant Window::getOption(int identifier) const
612 {
613 if (m_contentsWidget)
614 {
615 return m_contentsWidget->getOption(identifier);
616 }
617
618 return (m_session.options.contains(identifier) ? m_session.options[identifier] : SettingsManager::getOption(identifier, m_session.getUrl()));
619 }
620
getUrl() const621 QUrl Window::getUrl() const
622 {
623 return ((m_contentsWidget && !m_isAboutToClose) ? m_contentsWidget->getUrl() : m_session.getUrl());
624 }
625
getIcon() const626 QIcon Window::getIcon() const
627 {
628 return ((m_contentsWidget && !m_isAboutToClose) ? m_contentsWidget->getIcon() : HistoryManager::getIcon(m_session.getUrl()));
629 }
630
createThumbnail() const631 QPixmap Window::createThumbnail() const
632 {
633 return ((m_contentsWidget && !m_isAboutToClose) ? m_contentsWidget->createThumbnail() : QPixmap());
634 }
635
getLastActivity() const636 QDateTime Window::getLastActivity() const
637 {
638 return m_lastActivity;
639 }
640
getActionState(int identifier,const QVariantMap & parameters) const641 ActionsManager::ActionDefinition::State Window::getActionState(int identifier, const QVariantMap ¶meters) const
642 {
643 ActionsManager::ActionDefinition::State state(ActionsManager::getActionDefinition(identifier).getDefaultState());
644
645 switch (identifier)
646 {
647 case ActionsManager::CloneTabAction:
648 state.isEnabled = canClone();
649
650 break;
651 case ActionsManager::DetachTabAction:
652 state.isEnabled = (m_mainWindow->getWindowCount() > 1 || parameters.value(QLatin1String("minimalInterface")).toBool());
653
654 break;
655 case ActionsManager::PinTabAction:
656 state.text = (m_isPinned ? QCoreApplication::translate("actions", "Unpin Tab") : QCoreApplication::translate("actions", "Pin Tab"));
657
658 break;
659 case ActionsManager::CloseTabAction:
660 state.isEnabled = !m_isPinned;
661
662 break;
663 case ActionsManager::GoToParentDirectoryAction:
664 state.isEnabled = !Utils::isUrlEmpty(getUrl());
665
666 break;
667 case ActionsManager::MaximizeTabAction:
668 state.isEnabled = (getWindowState().state != Qt::WindowMaximized);
669
670 break;
671 case ActionsManager::MinimizeTabAction:
672 state.isEnabled = (getWindowState().state != Qt::WindowMinimized);
673
674 break;
675 case ActionsManager::RestoreTabAction:
676 state.isEnabled = (getWindowState().state != Qt::WindowNoState);
677
678 break;
679 case ActionsManager::AlwaysOnTopTabAction:
680 {
681 const QMdiSubWindow *subWindow(qobject_cast<QMdiSubWindow*>(parentWidget()));
682
683 if (subWindow)
684 {
685 state.isEnabled = subWindow->windowFlags().testFlag(Qt::WindowStaysOnTopHint);
686 }
687 }
688
689 break;
690 default:
691 if (m_contentsWidget)
692 {
693 state = m_contentsWidget->getActionState(identifier, parameters);
694 }
695
696 break;
697 }
698
699 return state;
700 }
701
getHistory() const702 WindowHistoryInformation Window::getHistory() const
703 {
704 if (m_contentsWidget)
705 {
706 return m_contentsWidget->getHistory();
707 }
708
709 WindowHistoryInformation history;
710 history.entries = m_session.history;
711 history.index = m_session.historyIndex;
712
713 return history;
714 }
715
getSession() const716 SessionWindow Window::getSession() const
717 {
718 const QMdiSubWindow *subWindow(qobject_cast<QMdiSubWindow*>(parentWidget()));
719 SessionWindow session;
720
721 if (m_contentsWidget)
722 {
723 const WindowHistoryInformation history(m_contentsWidget->getHistory());
724
725 if (m_contentsWidget->getType() == QLatin1String("web"))
726 {
727 const WebContentsWidget *webWidget(qobject_cast<WebContentsWidget*>(m_contentsWidget));
728
729 if (webWidget)
730 {
731 session.options = webWidget->getOptions();
732 }
733 }
734
735 session.history = history.entries;
736 session.parentGroup = 0;
737 session.historyIndex = history.index;
738 session.isPinned = isPinned();
739 }
740 else
741 {
742 session = m_session;
743 }
744
745 session.state = getWindowState();
746 session.isAlwaysOnTop = (subWindow && subWindow->windowFlags().testFlag(Qt::WindowStaysOnTopHint));
747
748 return session;
749 }
750
getWindowState() const751 WindowState Window::getWindowState() const
752 {
753 const QMdiSubWindow *subWindow(qobject_cast<QMdiSubWindow*>(parentWidget()));
754 WindowState windowState;
755 windowState.state = Qt::WindowMaximized;
756
757 if (subWindow && !subWindow->isMaximized())
758 {
759 if (subWindow->isMinimized())
760 {
761 windowState.state = Qt::WindowMinimized;
762 }
763 else
764 {
765 windowState.geometry = subWindow->geometry();
766 windowState.state = Qt::WindowNoState;
767 }
768 }
769
770 return windowState;
771 }
772
sizeHint() const773 QSize Window::sizeHint() const
774 {
775 return QSize(800, 600);
776 }
777
getLoadingState() const778 WebWidget::LoadingState Window::getLoadingState() const
779 {
780 return ((m_contentsWidget && !m_isAboutToClose) ? m_contentsWidget->getLoadingState() : WebWidget::DeferredLoadingState);
781 }
782
getContentState() const783 WebWidget::ContentStates Window::getContentState() const
784 {
785 return ((m_contentsWidget && !m_isAboutToClose) ? m_contentsWidget->getContentState() : WebWidget::UnknownContentState);
786 }
787
getIdentifier() const788 quint64 Window::getIdentifier() const
789 {
790 return m_identifier;
791 }
792
getZoom() const793 int Window::getZoom() const
794 {
795 return ((m_contentsWidget && !m_isAboutToClose) ? m_contentsWidget->getZoom() : m_session.getZoom());
796 }
797
canClone() const798 bool Window::canClone() const
799 {
800 return ((m_contentsWidget && !m_isAboutToClose) ? m_contentsWidget->canClone() : false);
801 }
802
canZoom() const803 bool Window::canZoom() const
804 {
805 return ((m_contentsWidget && !m_isAboutToClose) ? m_contentsWidget->canZoom() : false);
806 }
807
isAboutToClose() const808 bool Window::isAboutToClose() const
809 {
810 return m_isAboutToClose;
811 }
812
isActive() const813 bool Window::isActive() const
814 {
815 return (isActiveWindow() && isAncestorOf(QApplication::focusWidget()));
816 }
817
isPinned() const818 bool Window::isPinned() const
819 {
820 return m_isPinned;
821 }
822
isPrivate() const823 bool Window::isPrivate() const
824 {
825 return ((m_contentsWidget && !m_isAboutToClose) ? m_contentsWidget->isPrivate() : SessionsManager::calculateOpenHints(m_parameters).testFlag(SessionsManager::PrivateOpen));
826 }
827
event(QEvent * event)828 bool Window::event(QEvent *event)
829 {
830 if (event->type() == QEvent::ParentChange)
831 {
832 const QMdiSubWindow *subWindow(qobject_cast<QMdiSubWindow*>(parentWidget()));
833
834 if (subWindow)
835 {
836 connect(subWindow, &QMdiSubWindow::windowStateChanged, [&]()
837 {
838 emit arbitraryActionsStateChanged({ActionsManager::MaximizeTabAction, ActionsManager::MinimizeTabAction, ActionsManager::RestoreTabAction});
839 });
840 }
841 }
842
843 return QWidget::event(event);
844 }
845
846 }
847