/* This file is part of KDDockWidgets. SPDX-FileCopyrightText: 2020 Klarälvdalens Datakonsult AB, a KDAB Group company Author: Sérgio Martins SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only Contact KDAB at for commercial licensing options. */ #include "ViewWrapper_p.h" #include "core/View_p.h" #include "qtwidgets/views/DockWidget.h" #include "qtwidgets/views/DropArea.h" #include "qtwidgets/views/FloatingWindow.h" #include "qtwidgets/views/Group.h" #include "qtwidgets/views/MainWindow.h" #include "qtwidgets/views/MDILayout.h" #include "qtwidgets/views/Separator.h" #include "qtwidgets/views/SideBar.h" #include "qtwidgets/views/Stack.h" #include "qtwidgets/views/TabBar.h" #include "qtwidgets/views/TitleBar.h" #include "qtwidgets/views/RubberBand.h" #include "qtwidgets/Window_p.h" #include "qtwidgets/views/MDIArea.h" #include "kddockwidgets/core/MDILayout.h" #include "kddockwidgets/core/DropArea.h" #include "kddockwidgets/core/SideBar.h" #include #include using namespace KDDockWidgets; using namespace KDDockWidgets::QtWidgets; static Core::Controller *controllerForWidget(QWidget *widget) { // KDDW deals in views, but sometimes we might get a native type like QWidget, for example if // you call someview->window(). This function let's us retrieve the actual controller of the // stray QWidget. for (int i = int(Core::ViewType::FIRST); i <= int(Core::ViewType::LAST); i *= 2) { // Using a for+switch pattern so that compiler reminds us if new enumerators are added to // enum switch (Core::ViewType(i)) { case Core::ViewType::Group: if (auto view = qobject_cast(widget)) return view->controller(); break; case Core::ViewType::TitleBar: if (auto view = qobject_cast(widget)) return view->controller(); break; case Core::ViewType::TabBar: if (auto view = qobject_cast(widget)) return view->controller(); break; case Core::ViewType::Stack: if (auto view = qobject_cast(widget)) return view->controller(); break; case Core::ViewType::FloatingWindow: if (auto view = qobject_cast(widget)) return view->controller(); break; case Core::ViewType::Separator: if (auto view = qobject_cast(widget)) return view->controller(); break; case Core::ViewType::DockWidget: if (auto view = qobject_cast(widget)) return view->controller(); break; case Core::ViewType::DropArea: if (auto view = qobject_cast(widget)) return view->controller(); break; case Core::ViewType::MDILayout: if (auto view = qobject_cast(widget)) return view->controller(); break; case Core::ViewType::SideBar: if (auto view = qobject_cast(widget)) return view->controller(); break; case Core::ViewType::MainWindow: if (auto view = qobject_cast(widget)) return view->controller(); break; case Core::ViewType::RubberBand: case Core::ViewType::LayoutItem: case Core::ViewType::ViewWrapper: case Core::ViewType::DropAreaIndicatorOverlay: case Core::ViewType::None: // skip internal types continue; break; } } return nullptr; } /*static*/ std::shared_ptr ViewWrapper::create(QObject *widget) { return create(qobject_cast(widget)); } /*static*/ std::shared_ptr ViewWrapper::create(QWidget *widget) { if (!widget) return {}; auto wrapper = new ViewWrapper(widget); auto sharedptr = std::shared_ptr(wrapper); wrapper->d->m_thisWeakPtr = sharedptr; return sharedptr; } ViewWrapper::ViewWrapper(QObject *widget) : ViewWrapper(qobject_cast(widget)) { } ViewWrapper::ViewWrapper(QWidget *widget) : QtCommon::ViewWrapper(controllerForWidget(widget), widget) , m_widget(widget) { } QRect ViewWrapper::geometry() const { return m_widget->geometry(); } QPoint ViewWrapper::mapToGlobal(QPoint localPt) const { return m_widget->mapToGlobal(localPt); } QPoint ViewWrapper::mapFromGlobal(QPoint globalPt) const { return m_widget->mapFromGlobal(globalPt); } void ViewWrapper::setGeometry(QRect rect) { m_widget->setGeometry(rect); } std::shared_ptr ViewWrapper::window() const { if (m_widget->window()->windowHandle()) return std::shared_ptr(new Window(m_widget->window())); return nullptr; } bool ViewWrapper::isRootView() const { return m_widget->isWindow(); } void ViewWrapper::setVisible(bool is) { m_widget->setVisible(is); } bool ViewWrapper::isVisible() const { return m_widget->isVisible(); } bool ViewWrapper::isExplicitlyHidden() const { return m_widget->isHidden(); } void ViewWrapper::move(int x, int y) { m_widget->move(x, y); } void ViewWrapper::activateWindow() { m_widget->activateWindow(); } bool ViewWrapper::isMaximized() const { return m_widget->isMaximized(); } bool ViewWrapper::isMinimized() const { return m_widget->isMinimized(); } void ViewWrapper::setSize(int x, int y) { m_widget->resize(x, y); } bool ViewWrapper::is(Core::ViewType t) const { switch (t) { case Core::ViewType::Group: return qobject_cast(m_widget); case Core::ViewType::TitleBar: return qobject_cast(m_widget); case Core::ViewType::TabBar: return qobject_cast(m_widget); case Core::ViewType::Stack: return qobject_cast(m_widget); case Core::ViewType::FloatingWindow: return qobject_cast(m_widget); case Core::ViewType::Separator: return qobject_cast(m_widget); case Core::ViewType::DockWidget: return qobject_cast(m_widget); case Core::ViewType::SideBar: return qobject_cast(m_widget); case Core::ViewType::MainWindow: return qobject_cast(m_widget); case Core::ViewType::DropArea: return qobject_cast(m_widget); case Core::ViewType::MDILayout: return qobject_cast(m_widget); case Core::ViewType::RubberBand: return qobject_cast(m_widget); case Core::ViewType::LayoutItem: case Core::ViewType::None: case Core::ViewType::DropAreaIndicatorOverlay: qWarning() << Q_FUNC_INFO << "These are framework internals that are not wrapped"; return false; case Core::ViewType::ViewWrapper: return true; } qWarning() << Q_FUNC_INFO << "Unknown type" << static_cast(t); return false; } std::shared_ptr ViewWrapper::rootView() const { if (auto w = m_widget->window()) return std::shared_ptr(new ViewWrapper(w)); return {}; } std::shared_ptr ViewWrapper::parentView() const { if (auto p = m_widget->parentWidget()) return std::shared_ptr(new ViewWrapper(p)); return {}; } std::shared_ptr ViewWrapper::childViewAt(QPoint localPos) const { if (QWidget *child = m_widget->childAt(localPos)) return std::shared_ptr(new ViewWrapper(child)); return {}; } void ViewWrapper::grabMouse() { m_widget->grabMouse(); } void ViewWrapper::releaseMouse() { m_widget->releaseMouse(); } void ViewWrapper::setFocus(Qt::FocusReason reason) { m_widget->setFocus(reason); } QString ViewWrapper::viewName() const { return m_widget->QWidget::objectName(); } bool ViewWrapper::isNull() const { return m_widget.data() == nullptr; } QWidget *ViewWrapper::widget() const { return m_widget; } void ViewWrapper::setWindowTitle(const QString &title) { m_widget->setWindowTitle(title); } QPoint ViewWrapper::mapTo(Core::View *someAncestor, QPoint pos) const { auto *ancestorWidget = View_qt::asQWidget(someAncestor); if (ancestorWidget && m_widget->isAncestorOf(ancestorWidget)) { } else if (ancestorWidget) { for (auto *w = m_widget->parentWidget(); w; w = w->parentWidget()) { if (w == ancestorWidget) return m_widget->mapTo(ancestorWidget, pos); } } return ancestorWidget ? ancestorWidget->mapFromGlobal(m_widget->mapToGlobal(pos)) : pos; } bool ViewWrapper::hasAttribute(Qt::WidgetAttribute attr) const { return m_widget->testAttribute(attr); } void ViewWrapper::setCursor(Qt::CursorShape cursor) { m_widget->setCursor(cursor); } QSize ViewWrapper::minSize() const { const int minW = m_widget->minimumWidth() > 0 ? m_widget->minimumWidth() : m_widget->minimumSizeHint().width(); const int minH = m_widget->minimumHeight() > 0 ? m_widget->minimumHeight() : m_widget->minimumSizeHint().height(); return QSize(minW, minH).expandedTo(View::hardcodedMinimumSize()); } QVector> ViewWrapper::childViews() const { return QtWidgets::View::childViewsFor(m_widget); } void ViewWrapper::setParent(Core::View *parent) { QtWidgets::View::setParentFor(m_widget, parent); } bool ViewWrapper::close() { return m_widget->close(); } Qt::FocusPolicy ViewWrapper::focusPolicy() const { return m_widget->focusPolicy(); } void ViewWrapper::setFocusPolicy(Qt::FocusPolicy policy) { m_widget->setFocusPolicy(policy); } bool ViewWrapper::hasFocus() const { return m_widget->hasFocus(); } QSize ViewWrapper::maxSizeHint() const { return m_widget->maximumSize(); } void ViewWrapper::raiseAndActivate() { QtWidgets::View::raiseAndActivate(m_widget); }