8#include <QtCore/qtimer.h>
9#include <QtGui/qwindow.h>
10#include <QtGui/qguiapplication.h>
11#include <QtQuick/qquickwindow.h>
12#include <QtQuick/qquickitem.h>
13#include <QtQml/qqmlcomponent.h>
15#include <private/qqmlmetatype_p.h>
16#include <private/qquickpixmap_p.h>
17#include <private/qquickview_p.h>
18#include <private/qv4compileddata_p.h>
34 QCoreApplication::setQuitLockEnabled(quitLockEnabled);
40 const QWindowList windows = QGuiApplication::allWindows();
41 for (QWindow *window : windows)
51 return flags | Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint
52 | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint;
55 return flags | Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint;
64 m_dummyItem.reset(
new QQuickItem);
65 const QString platformName = QGuiApplication::platformName();
66 m_supportsMultipleWindows = (platformName == QStringLiteral(
"windows")
67 || platformName == QStringLiteral(
"cocoa")
68 || platformName == QStringLiteral(
"xcb")
69 || platformName == QStringLiteral(
"wayland"));
71 QCoreApplication::instance()->installEventFilter(
this);
82 if (window && (event->type() == QEvent::Move) &&
83 qobject_cast<QQuickWindow*>(obj) == window) {
84 m_lastPosition.takePosition(window);
87 return QObject::eventFilter(obj, event);
93 for (QObject *obj : m_createdObjects)
94 if (obj && ::qmlEngine(obj) == qmlEngine)
96 m_createdObjects.removeAll(
nullptr);
102 connect(service, &QQmlPreviewServiceImpl::drop,
this, &QQmlClassicPreviewHandler::dropCU);
104 connect(service, &QQmlPreviewServiceImpl::zoom,
this, &QQmlClassicPreviewHandler::zoom);
109 QSharedPointer<QuitLockDisabler> disabler(
new QuitLockDisabler);
112 m_component.reset(
nullptr);
113 QQuickPixmap::purgeCache();
115 const QList<QQmlEngine *> seenEngines = engines();
116 const int numEngines = seenEngines.size();
117 if (numEngines > 1) {
118 emit error(QString::fromLatin1(
"%1 QML engines available. We cannot decide which one "
119 "should load the component.").arg(numEngines));
121 }
else if (numEngines == 0) {
122 emit error(QLatin1String(
"No QML engines found."));
125 m_lastPosition.loadWindowPositionSettings(url);
127 QQmlEngine *engine = seenEngines.front();
128 engine->clearSingletons();
129 engine->clearComponentCache();
130 m_component.reset(
new QQmlComponent(engine, url,
this));
132 auto onStatusChanged = [disabler,
this](QQmlComponent::Status status) {
134 case QQmlComponent::Null:
135 case QQmlComponent::Loading:
137 case QQmlComponent::Ready:
140 case QQmlComponent::Error:
141 emit error(m_component->errorString());
148 disconnect(m_component.data(), &QQmlComponent::statusChanged,
this,
nullptr);
152 if (onStatusChanged(m_component->status()))
153 connect(m_component.data(), &QQmlComponent::statusChanged,
this, onStatusChanged);
160 while (
const auto cu = QQmlMetaType::obtainCompilationUnit(url))
161 QQmlMetaType::unregisterInternalCompositeType(cu);
166 if (m_component.isNull() || !m_component->isReady()) {
167 emit error(QLatin1String(
"Component is not ready."));
179 qDeleteAll(m_createdObjects);
180 m_createdObjects.clear();
186 if (!m_supportsMultipleWindows)
188 QObject *object = m_component->create();
189 m_createdObjects.append(object);
195 if (QWindow *window = qobject_cast<QWindow *>(object)) {
197 for (QWindow *otherWindow : QGuiApplication::allWindows()) {
198 if (QQuickWindow *quickWindow = qobject_cast<QQuickWindow *>(otherWindow)) {
199 if (quickWindow == currentWindow())
201 quickWindow->setVisible(
false);
202 quickWindow->setFlags(quickWindow->flags() & ~Qt::WindowStaysOnTopHint);
205 }
else if (QQuickItem *item = qobject_cast<QQuickItem *>(object)) {
207 for (QWindow *window : QGuiApplication::allWindows()) {
208 if (QQuickWindow *quickWindow = qobject_cast<QQuickWindow *>(window)) {
209 if (currentWindow() !=
nullptr) {
210 emit error(QLatin1String(
"Multiple QQuickWindows available. We cannot "
211 "decide which one to use."));
214 setCurrentWindow(quickWindow);
216 window->setVisible(
false);
217 window->setFlag(Qt::WindowStaysOnTopHint,
false);
223 m_createdObjects.append(currentWindow());
226 for (QQuickItem *oldItem : currentWindow()->contentItem()->childItems())
227 oldItem->setParentItem(m_dummyItem.data());
231 if (QQuickView *view = qobject_cast<QQuickView *>(currentWindow()))
232 QQuickViewPrivate::get(view)->setRootObject(item);
240 emit error(QLatin1String(
"Created object is neither a QWindow nor a QQuickItem."));
244 m_lastPosition.initLastSavedWindowPosition(window);
245 window->setFlags(fixFlags(window->flags()) | Qt::WindowStaysOnTopHint);
246 window->setVisible(
true);
252 m_zoomFactor = newFactor;
253 QTimer::singleShot(0,
this, [
this, newFactor]() {
254 zoomWindow(currentWindow(), newFactor, &m_lastPosition);
260#include "moc_qqmlclassicpreviewhandler.cpp"
void load(const QUrl &url) final
void removeEngine(QQmlEngine *engine) final
void connectToService(QQmlPreviewServiceImpl *service) final
~QQmlClassicPreviewHandler() override
bool eventFilter(QObject *obj, QEvent *event) final
Filters events if this object has been installed as an event filter for the watched object.
void setCurrentRootItem(QQuickItem *item)
void setCurrentWindow(QQuickWindow *window)
virtual void removeEngine(QQmlEngine *engine)
QQuickWindow * currentWindow() const
virtual void connectToService(QQmlPreviewServiceImpl *service)
Combined button and popup list for selecting options.
static Qt::WindowFlags fixFlags(Qt::WindowFlags flags)
static void closeAllWindows()
const bool quitLockEnabled