diff options
author | Svetlana Abramenkova <sabramenkova@luxoft.com> | 2019-03-14 10:09:22 +0300 |
---|---|---|
committer | Svetlana Abramenkova <sabramenkova@luxoft.com> | 2019-03-14 10:09:54 +0300 |
commit | c0eabe1bb8da128a1d4eca73cbb6704882c6ff1b (patch) | |
tree | 268ce1fd8032dd0c9ae610f2378ab9732027cee5 | |
parent | 0c7bf141b08aa9e757e91a4a05769257d043eab2 (diff) | |
parent | 81b3f3e63ae0739d4e4840e4f401f78d829e0daf (diff) |
Merge remote-tracking branch 'origin/5.12' into dev
Change-Id: I7d49cb81bcd6bc4c3292bd2e9b7225cc47f462de
157 files changed, 1953 insertions, 372 deletions
diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..6b2abde --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +.tag export-subst +.gitattributes export-ignore +.gitignore export-ignore @@ -23,3 +23,4 @@ branch-coverage *.so *.pc .qmake.stash +*.qmlc diff --git a/.qmake.conf b/.qmake.conf index 03d3435..df1bf88 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -2,4 +2,4 @@ SOURCE_DIR=$$PWD BUILD_DIR=$$shadowed($$PWD) QMAKEFEATURES=$$SOURCE_DIR/qmake-features -VERSION = 1.0.0 +VERSION = 5.12.1 @@ -0,0 +1 @@ +$Format:%H$ diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 16a0a66..9ca10d5 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -7,4 +7,4 @@ * Juergen Bocklage-Ryannel - For providing the initial idea and believing into the product. -Copyright (C) 2016 Pelagicore AG +Copyright (C) 2019 Luxoft Sweden AB @@ -30,4 +30,4 @@ target. The documentation will be avilable at 'doc/qmllive/index.html'. -Copyright (C) 2016 Pelagicore AG +Copyright (C) 2019 Luxoft Sweden AB diff --git a/LICENSE.GPL3 b/LICENSE.GPL3 index 4809d25..94a9ed0 100644 --- a/LICENSE.GPL3 +++ b/LICENSE.GPL3 @@ -1,13 +1,3 @@ - GNU GENERAL PUBLIC LICENSE - - QmlLive is Copyright (C) 2016 Pelagicore AG - Contact: http://www.pelagicore.com/ - - You may use, distribute and copy Qt IVI under the terms of the - GNU General Public License version 3, which is displayed below. - -------------------------------------------------------------------------- - GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @@ -7,4 +7,4 @@ It is available for the PC but also for an embedded device, which supports Qt5. More information is available form documentation (see install instructions). -Copyright (C) 2016 Pelagicore AG +Copyright (C) 2019 Luxoft Sweden AB diff --git a/doc/QmlLiveDoc b/doc/QmlLiveDoc new file mode 100644 index 0000000..c19b528 --- /dev/null +++ b/doc/QmlLiveDoc @@ -0,0 +1,8 @@ +#include "logger.h" +#include "logreceiver.h" +#include "ipc/ipcserver.h" +#include "ipc/ipcclient.h" +#include "livehubengine.h" +#include "livenodeengine.h" +#include "remotepublisher.h" +#include "remotereceiver.h" diff --git a/doc/concepts.qdoc b/doc/concepts.qdoc index 73e1634..26d79c6 100644 --- a/doc/concepts.qdoc +++ b/doc/concepts.qdoc @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -34,7 +35,7 @@ \page qmllive-concepts.html \title Concepts -\chapter Live Reloading +\section1 Live Reloading During a typical user interface design phase, designers create many graphical documents describing the desired user interface. Transferring such graphical @@ -69,11 +70,11 @@ For a local session you only need the QmlLive Bench. It contains all of the required components in an easy-to-use interface. You type and save, we show you the outcome on your PC in a fraction of a second. This is ideally suited for a multi-monitor setup where you see your code on one display and the -the live results of your changes on the other display. Seamless user -interface creation is the target, where you see every change immediately. This +live results of your changes on the other display. Seamless user interface +creation is the target, where you see every change immediately. This is great for sketching out a scene or getting the last touch on animation behavior. It also encourages you to think in terms of components; instead of -developing a whole scene, you can can break apart the scene into smaller parts +developing a whole scene, you can break apart the scene into smaller parts or components. You can work on these small components and see how they look standalone or embedded into a larger scene. @@ -94,7 +95,7 @@ you can also connect more devices, or devices with different sizes. \image runtime.png -\chapter Display, Screens, Panels, Components, Fragments +\section1 Display, Screens, Panels, Components, Fragments \code +- Display @@ -131,7 +132,7 @@ and its screen navigation structure, and of the structure of individual screens their panels. It is also required to define a common set of components to be used inside the panels. The fragments are implementation-specific. -\chapter UX Sheets - \e{visual component testing} +\section1 UX Sheets - \e{visual component testing} UXSheet gives guidance on how to successfully develop user interface components with diff --git a/doc/doc.pri b/doc/doc.pri index b6dae4e..711e065 100644 --- a/doc/doc.pri +++ b/doc/doc.pri @@ -1,15 +1,2 @@ -build_online_docs: { - QMAKE_DOCS_TARGETDIR = qmllive - QMAKE_DOCS = $$PWD/qmllive-online.qdocconf -} else { - QMAKE_DOCS = $$PWD/qmllive.qdocconf -} - CONFIG += prepare_docs load(qt_docs_targets) - -OTHER_FILES += \ - $$PWD/*.qdocconf \ - $$PWD/*.qdoc \ - $$PWD/examples/*.qdoc \ - $$PWD/images/*.png diff --git a/doc/doc.pro b/doc/doc.pro new file mode 100644 index 0000000..4c486dc --- /dev/null +++ b/doc/doc.pro @@ -0,0 +1,19 @@ +TEMPLATE = aux + +CONFIG += force_qt +QT *= quick network + +build_online_docs: { + QMAKE_DOCS_TARGETDIR = qmllive + QMAKE_DOCS = $$PWD/qmllive-online.qdocconf +} else { + QMAKE_DOCS = $$PWD/qmllive.qdocconf +} + +include(doc.pri) + +OTHER_FILES += \ + $$PWD/*.qdocconf \ + $$PWD/*.qdoc \ + $$PWD/examples/*.qdoc \ + $$PWD/images/*.png diff --git a/doc/examples.qdoc b/doc/examples.qdoc index 0b8c0c0..04eb651 100644 --- a/doc/examples.qdoc +++ b/doc/examples.qdoc @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -36,6 +37,7 @@ \list \li \l{contentplugin}{Content Plugin} + \li \l{customruntime}{Custom Runtime} \endlist */ diff --git a/doc/examples/contentplugin.qdoc b/doc/examples/contentplugin.qdoc index a62267e..7334c6c 100644 --- a/doc/examples/contentplugin.qdoc +++ b/doc/examples/contentplugin.qdoc @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -32,7 +33,7 @@ \example contentplugin \title ContentPlugin Example - \brief Demonstrates how to write a Content Plugin for QmlLive + \brief Demonstrates how to write a Content Plugin for QmlLive. \image contentplugin-example.png Screenshot of the Plugin in Action diff --git a/doc/examples/customruntime.qdoc b/doc/examples/customruntime.qdoc new file mode 100644 index 0000000..58edada --- /dev/null +++ b/doc/examples/customruntime.qdoc @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QmlLive tool. +** +** $QT_BEGIN_LICENSE:GPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite licenses may use +** this file in accordance with the commercial license agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and The Qt Company. For +** licensing terms and conditions see https://www.qt.io/terms-conditions. +** For further information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: GPL-3.0 +** +****************************************************************************/ +/*! +\example customruntime +\title Custom Runtime Example + +\brief Demonstrates how to create a Custom QmlLive Runtime. + +\image customruntime-example.png Screenshot of the Custom QmlLive Runtime + +Creating a custom runtime with QmlLive features allows you to use your QML +view setup, combined with additional C++ code and the QmlLive system. + +Start with the \l LiveNodeEngine class. We need to modify this class to be +able to receive workspace changes and active document updates. By default, +the IPC listens to port 10234. + +The code snippet below shows a minimal custom QmlLive runtime: + +\snippet customruntime/main.cpp 0 + +To specify project depedencies on platforms that support \c pkg-config, +add the following line to your project file. This is assuming QmlLive is +installed on your build host: + +\code +CONFIG += link_pkgconfig +PKGCONFIG += qmllive +\endcode + +In case if your system doesn't support \c pkg-config, to compile everything +directly into your application, include file \c{$(QMLLIVEPROJECT)/src/src.pri} +by adding the line into your project file: + +\code +include(src.pri) +\endcode +*/ diff --git a/doc/images/customruntime-example.png b/doc/images/customruntime-example.png Binary files differnew file mode 100644 index 0000000..d5aba33 --- /dev/null +++ b/doc/images/customruntime-example.png diff --git a/doc/index.qdoc b/doc/index.qdoc index c560534..64265ce 100644 --- a/doc/index.qdoc +++ b/doc/index.qdoc @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -32,11 +33,11 @@ /*! \page qmllive-index.html -\keyword Pelagicore QmlLive Reference Documentation +\keyword QmlLive Reference Documentation \indexpage \title Qt QmlLive -\chapter Overview +\section1 Overview Qt QmlLive is a local and remote Qt Quick live reloading system. It allows you to change your QML user interface source code and view the result in almost @@ -58,7 +59,7 @@ your work so much more delightful. \endquotation -\chapter Contents +\section1 Contents The content of the documentation: diff --git a/doc/installation.qdoc b/doc/installation.qdoc index bf552b4..96b2d90 100644 --- a/doc/installation.qdoc +++ b/doc/installation.qdoc @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -34,15 +35,14 @@ \page qmllive-installation.html \title Installation -\chapter Dependencies +\section1 Dependencies \list \li Windows, Linux or macOS \li Qt5.4 or higher \endlist - -\chapter Building for desktop +\section1 Building for desktop \code $ qmake @@ -57,7 +57,7 @@ QmlLive Bench can be started directly from build directory by executing \endcode -\chapter Building for device +\section1 Building for device \e{Note: Only needed when you want to have live reloading enabled on the target.} @@ -78,7 +78,7 @@ Optionally it can be packaged with the help of \endcode -\chapter Building documentation +\section1 Building documentation \code $ qmake CONFIG+=force_independent @@ -88,7 +88,7 @@ Optionally it can be packaged with the help of The documentation will be available at \tt{doc/qmllive/index.html}. -\chapter Build options reference +\section1 Build options reference The following values can be added to qmake \c CONFIG variable: @@ -134,7 +134,7 @@ The following custom qmake variables are recognized: \row \li EXAMPLES_PREFIX \li Installation prefix for examples. Defaults to - \c{$$[QT_INSTALL_LIBS]/qmllive/examples}. + \c{$$[QT_INSTALL_EXAMPLES]/qmllive}. \row \li QMLLIVE_VERSION_EXTRA diff --git a/doc/ipc-group.qdoc b/doc/ipc-group.qdoc index a07a59a..7c9363f 100644 --- a/doc/ipc-group.qdoc +++ b/doc/ipc-group.qdoc @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -33,8 +34,8 @@ /*! \module ipc - \title IPC related classes - \brief A simple IPC solution for calling method on remote objects + \title IPC Related Classes + \brief A simple IPC solution for calling method on remote objects. The IPC is based on the idea to have a server with individual connections to clients and a client. The server is waiting for method calls from the diff --git a/doc/qmllive-group.qdoc b/doc/qmllive-group.qdoc index 7c41db1..1692595 100644 --- a/doc/qmllive-group.qdoc +++ b/doc/qmllive-group.qdoc @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -34,7 +35,8 @@ \module qmllive \title QmlLive Module - \brief Classes for watching a workspace and for local and remote reloading of Qt Quick user interfaces + \brief Classes for watching a workspace and for local and remote reloading + of Qt Quick user interfaces. The QmlLive module allows a developer to quickly create his own instance of a QmlLive workbench or a QmlLive runtime. diff --git a/doc/qmllive-online.qdocconf b/doc/qmllive-online.qdocconf index 087139e..d02e78f 100644 --- a/doc/qmllive-online.qdocconf +++ b/doc/qmllive-online.qdocconf @@ -2,7 +2,7 @@ HTML.footer = \ " </div>\n" \ " <p class=\"copy-notice\">\n" \ - " <acronym title=\"Copyright\">©</acronym> 2016 Pelagicore AG.\n" \ + " <acronym title=\"Copyright\">©</acronym> 2019 Luxoft Sweden AB.\n" \ " Documentation contributions included herein are the copyrights of\n" \ " their respective owners. " \ " The documentation provided herein is licensed under the terms of the" \ diff --git a/doc/qmllive-project.qdocconf b/doc/qmllive-project.qdocconf index 5744d9f..6933d29 100644 --- a/doc/qmllive-project.qdocconf +++ b/doc/qmllive-project.qdocconf @@ -1,8 +1,11 @@ project = QmlLive -description = Pelagicore QmlLive Reference Documentation +description = QmlLive Reference Documentation url = https://doc.qt.io/QtQmlLive version = $QT_VERSION +moduleheader = QmlLiveDoc +includepaths += -I ../src + sources.fileextensions = "*.cpp *.qdoc *.mm *.qml" headers.fileextensions = "*.h *.ch *.h++ *.hh *.hpp *.hxx" @@ -37,5 +40,8 @@ qhp.QmlLive.subprojects.manual.title = Qt QmlLive qhp.QmlLive.subprojects.manual.indexTitle = Qt QmlLive qhp.QmlLive.subprojects.manual.type = manual -navigation.homepage = "Qt QmlLive" +depends = qtcore qtqml qtquick qtnetwork qtautomotivesuite + +navigation.homepage = "Qt Automotive Suite" +navigation.landingpage = "Qt QmlLive" buildversion = "Qt QmlLive $QT_VERSION" diff --git a/doc/qmllive.qdocconf b/doc/qmllive.qdocconf index 91c033c..5e8615b 100644 --- a/doc/qmllive.qdocconf +++ b/doc/qmllive.qdocconf @@ -9,7 +9,7 @@ HTML.footer = \ "</div>\n" \ "<div class=\"footer\">\n" \ " <p>\n" \ - " <acronym title=\"Copyright\">©</acronym> 2016 Pelagicore AG.\n" \ + " <acronym title=\"Copyright\">©</acronym> 2019 Luxoft Sweden AB.\n" \ " Documentation contributions included herein are the copyrights of\n" \ " their respective owners.<br>" \ " The documentation provided herein is licensed under the terms of the" \ diff --git a/doc/usage.qdoc b/doc/usage.qdoc index 3a669a6..1fa6d17 100644 --- a/doc/usage.qdoc +++ b/doc/usage.qdoc @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -34,7 +35,7 @@ \page qmllive-usage.html \title Usage -\chapter Introduction +\section1 Introduction The QmlLive system was designed from the ground up to support your needs. It is structured in a modular fashion to be able to meet various usage @@ -52,7 +53,7 @@ For C++ developers, we also offer the ability to integrate the QmlLive system into your own custom runtime using our \l LiveNodeEngine class with a few lines of code and then use the QmlLive Bench to control it. -\chapter The Workbench +\section1 The Workbench The standard workbench is the all inclusive QML live reloading tool. It allows you to select a workspace to watch over and provides a default QML runtime for the @@ -74,12 +75,35 @@ Usage qmllivebench [options] <workspace> Usage qmllivebench [options] <workspace/file.qml> options: + -version ...........................displays version information. -pluginpath ........................path to QmlLive plugins -importpath ........................path to the QML import path -stayontop .........................keep viewer window on top + -addhost <name,address[,port]> .....add or update remote host configuration and exit + -rmhost <name> .....................remove remote host configuration and exit + -probehost <name> ..................suggest host became online and should be + connected (implies --remoteonly) + -noremote ..........................do not try to talk to a running bench, do + not listen for remote connections. + -remoteonly ........................talk to a running bench, do nothing if none + is running. + -ping ..............................just check if there is a bench running and + accepting remote connections. + -maxdirwatch <number> ..............limit the number of directories to watch for + changes + -project ...........................loads project document .qmllive containing + workspace path, imports paths, main document + in JSON format + +Arguments: + workspace ..........................workspace folder to watch. If this points to + a QML document, than the directory is + asssumed to be the workspace and the file the + active document. + document ...........................main QML document to load initially. \endcode -\chapter Qt Creator Integration +\section1 Qt Creator Integration You can integrate the QmlLive Bench into Qt Creator as an external tool. For this you need to open the Settings/Options dialog from Qt Creator and open the @@ -102,7 +126,7 @@ current project root folder open as workspace. -\chapter QmlLive Runtime +\section1 QmlLive Runtime A default runtime is provided by the QmlLive Runtime tool. It provides a default qml viewer and listens on a given port for IPC calls from @@ -123,6 +147,7 @@ Usage of the runtime Usage qmlliveruntime [options] <workspace> options: + -version ...........................displays version information. -ipcport <port> ....................the port the IPC shall listen on -updates-as-overlay ................allow receiving updates with read only workspace -update-on-connect .................update all workspace documents initially (blocking) @@ -149,7 +174,7 @@ this is used all workspace documents will be updated prior to instantiation of any QML component. -\chapter Custom Runtime +\section1 Custom Runtime You can create your own custom runtime with the QmlLive features. This allows you to use your QML view setup with your additional C++ code together with the QmlLive system. @@ -159,7 +184,7 @@ on the port 10234. Here is a short example of a minimal custom QmlLive runtime: -\snippet ../examples/app/main.cpp 0 +\snippet ../examples/customruntime/main.cpp 0 On platforms where pkg-config is supported simply add the following to your project file if QmlLive is installed on your build host: diff --git a/examples/app/app.pro b/examples/app/app.pro deleted file mode 100644 index cc41e36..0000000 --- a/examples/app/app.pro +++ /dev/null @@ -1,27 +0,0 @@ -TEMPLATE = app -TARGET = app -CONFIG += c++11 - -macx*: CONFIG -= app_bundle -QT *= quick - -include(../../src/lib.pri) - -SOURCES += main.cpp - -target.path = $$EXAMPLES_PREFIX/app -INSTALLS += target - -qml.files = \ - qml/customruntime-item.qml \ - qml/customruntime-window.qml \ - qml/item.qml \ - qml/window.qml -qml.path = $$EXAMPLES_PREFIX/app/qml -INSTALLS += qml -OTHER_FILES += $$qml.files - -icon.files = icon.png -icon.path = $$EXAMPLES_PREFIX/app -INSTALLS += icon -OTHER_FILES += $$icon.files diff --git a/examples/contentplugin/contentplugin.pro b/examples/contentplugin/contentplugin.pro index c142b07..da2d0a2 100644 --- a/examples/contentplugin/contentplugin.pro +++ b/examples/contentplugin/contentplugin.pro @@ -1,13 +1,19 @@ TEMPLATE = lib -CONFIG += plugin +CONFIG += plugin c++11 +QT += qml + +include(../../src/lib.pri) + INCLUDEPATH += ../../src HEADERS = mycontentadapterplugin.h SOURCES = mycontentadapterplugin.cpp TARGET = myContentAdapterPlugin DESTDIR = ../../bin/plugins -RESOURCES += res.qrc \ - res.qrc +RESOURCES += res.qrc OTHER_FILES += \ plugin.qml + +target.path = $$EXAMPLES_PREFIX/contentplugin +INSTALLS += target diff --git a/examples/contentplugin/mycontentadapterplugin.cpp b/examples/contentplugin/mycontentadapterplugin.cpp index cf419a1..1e5b0b6 100644 --- a/examples/contentplugin/mycontentadapterplugin.cpp +++ b/examples/contentplugin/mycontentadapterplugin.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -31,7 +32,7 @@ #include "mycontentadapterplugin.h" #include <QtCore/QtPlugin> -#include <QtDeclarative/QDeclarativeContext> +#include <QQmlContext> MyContentAdapterPlugin::MyContentAdapterPlugin(QObject *parent) : QObject(parent) @@ -63,12 +64,11 @@ bool MyContentAdapterPlugin::canAdapt(const QUrl &url) const //! [0] //! [1] -QUrl MyContentAdapterPlugin::adapt(const QUrl &url, QDeclarativeContext *context) + +QUrl MyContentAdapterPlugin::adapt(const QUrl &url, QQmlContext *context) { context->setContextProperty("imageSource", url); return QString("qrc:/mycontentadatperplugin/plugin.qml"); } //! [1] - -Q_EXPORT_PLUGIN2(myContentAdapterPlugin, MyContentAdapterPlugin) diff --git a/examples/contentplugin/mycontentadapterplugin.h b/examples/contentplugin/mycontentadapterplugin.h index ebac836..a70bc5c 100644 --- a/examples/contentplugin/mycontentadapterplugin.h +++ b/examples/contentplugin/mycontentadapterplugin.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -40,6 +41,7 @@ class MyContentAdapterPlugin : public QObject, public ContentAdapterInterface //! [1] Q_INTERFACES(ContentAdapterInterface) //! [1] + Q_PLUGIN_METADATA(IID "io.qt.QMLLive.ContentPlugin") public: explicit MyContentAdapterPlugin(QObject *parent = 0); @@ -47,8 +49,8 @@ public: QImage preview(const QString& path, const QSize &requestedSize); bool canAdapt(const QUrl& url) const; - QUrl adapt(const QUrl& url, QDeclarativeContext* context); + QUrl adapt(const QUrl& url, QQmlContext* context); }; //! [0] diff --git a/examples/contentplugin/plugin.qml b/examples/contentplugin/plugin.qml index e77d4c1..c0c5ea8 100644 --- a/examples/contentplugin/plugin.qml +++ b/examples/contentplugin/plugin.qml @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/examples/customruntime/customruntime.pro b/examples/customruntime/customruntime.pro new file mode 100644 index 0000000..90920fb --- /dev/null +++ b/examples/customruntime/customruntime.pro @@ -0,0 +1,23 @@ +TEMPLATE = app +TARGET = customruntime +CONFIG += c++11 + +macx*: CONFIG -= app_bundle +QT *= quick + +include(../../src/lib.pri) + +SOURCES += main.cpp + +target.path = $$EXAMPLES_PREFIX/customruntime +INSTALLS += target + +qml.files = qml/*.qml +qml.path = $$target.path/qml +INSTALLS += qml +OTHER_FILES += $$qml.files + +icon.files = icon.png +icon.path = $$target.path +INSTALLS += icon +OTHER_FILES += $$icon.files diff --git a/examples/app/icon.png b/examples/customruntime/icon.png Binary files differindex 1bf2581..1bf2581 100644 --- a/examples/app/icon.png +++ b/examples/customruntime/icon.png diff --git a/examples/app/main.cpp b/examples/customruntime/main.cpp index d02c60d..1050432 100644 --- a/examples/app/main.cpp +++ b/examples/customruntime/main.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -54,7 +55,7 @@ public: int main(int argc, char **argv) { QGuiApplication app(argc, argv); - MyQmlApplicationEngine engine(QStringLiteral("qml/window.qml")); + MyQmlApplicationEngine engine(QStringLiteral("qml/customruntime-window.qml")); if (!qEnvironmentVariableIsSet("MY_APP_ENABLE_QMLLIVE")) return app.exec(); diff --git a/examples/app/qml/customruntime-item.qml b/examples/customruntime/qml/customruntime-item.qml index bd95044..942a5af 100644 --- a/examples/app/qml/customruntime-item.qml +++ b/examples/customruntime/qml/customruntime-item.qml @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -29,6 +30,7 @@ ** ****************************************************************************/ +//! [1] import QtQuick 2.0 ListView { @@ -51,3 +53,4 @@ ListView { } } } +//! [1] diff --git a/examples/app/qml/customruntime-window.qml b/examples/customruntime/qml/customruntime-window.qml index 8d9dc3b..a722f16 100644 --- a/examples/app/qml/customruntime-window.qml +++ b/examples/customruntime/qml/customruntime-window.qml @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -29,6 +30,7 @@ ** ****************************************************************************/ +//! [2] import QtQuick 2.0 import QtQuick.Window 2.2 @@ -61,3 +63,4 @@ Window { } } } +//! [2] diff --git a/examples/examples.pro b/examples/examples.pro index 202f1f1..67d00d6 100644 --- a/examples/examples.pro +++ b/examples/examples.pro @@ -1,3 +1,5 @@ +include(../doc/doc.pri) TEMPLATE = subdirs -SUBDIRS = \ - app \ +SUBDIRS += customruntime \ + contentplugin + diff --git a/header.GPL-QTAS b/header.GPL-QTAS index 1226d68..9a57b98 100644 --- a/header.GPL-QTAS +++ b/header.GPL-QTAS @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/qmllive.pri b/qmllive.pri index 6487905..1494509 100755 --- a/qmllive.pri +++ b/qmllive.pri @@ -4,7 +4,7 @@ android|ios|qnx { } isEmpty(PREFIX): PREFIX = $$[QT_INSTALL_PREFIX] -isEmpty(EXAMPLES_PREFIX): EXAMPLES_PREFIX = $$[QT_INSTALL_LIBS]/qmllive/examples +isEmpty(EXAMPLES_PREFIX): EXAMPLES_PREFIX = $$[QT_INSTALL_EXAMPLES]/qmllive VERSIONS = $$split(VERSION, ".") VERSION_MAJOR = $$member(VERSIONS, 0) diff --git a/qmllive.pro b/qmllive.pro index 9aeb50f..12c7a4d 100755 --- a/qmllive.pro +++ b/qmllive.pro @@ -1,10 +1,11 @@ !skip-bench: requires(qtHaveModule(widgets)) requires(!winrt:!integrity) +requires(!wasm) +requires(!ios) load(configure) load(config-output) include(qmllive.pri) -include(doc/doc.pri) !skip-bench:!minQtVersion(5, 4, 0): error("You need at least Qt 5.4.0 to build QmlLive Bench") !skip-tests:!minQtVersion(5, 4, 0): error("You need at least Qt 5.4.0 to build QmlLive tests") @@ -16,6 +17,9 @@ CONFIG += ordered SUBDIRS += src !skip-tests: SUBDIRS += tests !skip-examples: SUBDIRS += examples +SUBDIRS += doc + +include(doc/doc.pri) OTHER_FILES += \ README.md \ diff --git a/src/bench/aboutdialog.cpp b/src/bench/aboutdialog.cpp index c9c37bf..2fc61b5 100644 --- a/src/bench/aboutdialog.cpp +++ b/src/bench/aboutdialog.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -41,7 +42,7 @@ AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent) { - setWindowTitle(tr("About Qt QML Live")); + setWindowTitle(tr("About Qt QmlLive")); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); QVBoxLayout *layout = new QVBoxLayout(this); diff --git a/src/bench/aboutdialog.h b/src/bench/aboutdialog.h index e44f707..9932757 100644 --- a/src/bench/aboutdialog.h +++ b/src/bench/aboutdialog.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/bench/allhostswidget.cpp b/src/bench/allhostswidget.cpp index 114eba7..9d0e07d 100644 --- a/src/bench/allhostswidget.cpp +++ b/src/bench/allhostswidget.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/bench/allhostswidget.h b/src/bench/allhostswidget.h index a53785f..b4969f5 100644 --- a/src/bench/allhostswidget.h +++ b/src/bench/allhostswidget.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/examples/app/qml/window.qml b/src/bench/appearanceoptionpage.cpp index 757c63e..ab4da2f 100644 --- a/examples/app/qml/window.qml +++ b/src/bench/appearanceoptionpage.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2018 Luxoft Sweden AB ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -29,35 +29,27 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import QtQuick.Window 2.2 +#include "appearanceoptionpage.h" +#include "ui_appearanceoptionpage.h" -Window { - id: window - width: 100 - height: 100 - visible: true +AppearanceOptionPage::AppearanceOptionPage(QWidget *parent) + : QWidget(parent) + , ui(new Ui::AppearanceOptionPage) +{ + ui->setupUi(this); + QSettings s; + ui->fileFilter->setChecked(s.value("only_qml_files/enabled").toBool()); +} - ListView { - // TODO: Make it work with 'anchors.fill: parent'. Window size seems to - // be propagated too late to the contentItem, giving zero size initially. - width: window.width - height: window.height +AppearanceOptionPage::~AppearanceOptionPage() +{ + delete ui; +} - model: ["red", "green", "blue", "black"] - delegate: Rectangle { - width: ListView.view.width - height: 25 - color: model.modelData - Image { - anchors.left: parent.left - source: "../icon.png" - } - Text { - x: 25 - text: model.modelData - color: "white" - } - } - } +void AppearanceOptionPage::apply() +{ + bool enabled = ui->fileFilter->isChecked(); + QSettings s; + s.setValue("only_qml_files/enabled", enabled); + emit hideNonQMLFiles(enabled); } diff --git a/examples/app/qml/item.qml b/src/bench/appearanceoptionpage.h index 9b63a15..f6cc39c 100644 --- a/examples/app/qml/item.qml +++ b/src/bench/appearanceoptionpage.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2018 Luxoft Sweden AB ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -29,25 +29,32 @@ ** ****************************************************************************/ -import QtQuick 2.0 +#ifndef APPEARANCEOPTIONSPAGE_H +#define APPEARANCEOPTIONSPAGE_H -ListView { - width: 100 - height: 100 +#include <QtCore> +#include <QtGui> - model: ["red", "green", "blue", "black"] - delegate: Rectangle { - width: ListView.view.width - height: 25 - color: model.modelData - Image { - anchors.left: parent.left - source: "../icon.png" - } - Text { - x: 25 - text: model.modelData - color: "white" - } - } +#include <QtWidgets> + +QT_BEGIN_NAMESPACE +namespace Ui { +class AppearanceOptionPage; } +QT_END_NAMESPACE + +class AppearanceOptionPage : public QWidget +{ + Q_OBJECT +public: + explicit AppearanceOptionPage(QWidget *parent = nullptr); + ~AppearanceOptionPage(); + void apply(); + +signals: + void hideNonQMLFiles(bool hide); +private: + Ui::AppearanceOptionPage *ui; +}; + +#endif // APPEARANCEOPTIONSPAGE_H diff --git a/src/bench/appearanceoptionpage.ui b/src/bench/appearanceoptionpage.ui new file mode 100644 index 0000000..476fa99 --- /dev/null +++ b/src/bench/appearanceoptionpage.ui @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>AppearanceOptionPage</class> + <widget class="QWidget" name="AppearanceOptionPage"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <widget class="QCheckBox" name="fileFilter"> + <property name="geometry"> + <rect> + <x>10</x> + <y>10</y> + <width>271</width> + <height>20</height> + </rect> + </property> + <property name="text"> + <string>Hide non QML files in workspace view</string> + </property> + </widget> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/bench/autodiscoveryhostsdialog.cpp b/src/bench/autodiscoveryhostsdialog.cpp index e4e0a2c..a161949 100644 --- a/src/bench/autodiscoveryhostsdialog.cpp +++ b/src/bench/autodiscoveryhostsdialog.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/bench/autodiscoveryhostsdialog.h b/src/bench/autodiscoveryhostsdialog.h index 889d71c..771126c 100644 --- a/src/bench/autodiscoveryhostsdialog.h +++ b/src/bench/autodiscoveryhostsdialog.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/bench/bench.pro b/src/bench/bench.pro index d6a94ae..df2b09a 100644 --- a/src/bench/bench.pro +++ b/src/bench/bench.pro @@ -27,7 +27,9 @@ SOURCES += \ importpathoptionpage.cpp \ hostdiscoverymanager.cpp \ autodiscoveryhostsdialog.cpp \ - options.cpp + options.cpp \ + newprojectwizard.cpp \ + appearanceoptionpage.cpp HEADERS += \ aboutdialog.h \ @@ -48,14 +50,17 @@ HEADERS += \ httpproxyoptionpage.h \ hostdiscoverymanager.h \ autodiscoveryhostsdialog.h \ - options.h + options.h \ + newprojectwizard.h \ + appearanceoptionpage.h FORMS += \ optionsdialog.ui \ hostsoptionpage.ui \ httpproxyoptionpage.ui \ importpathoptionpage.ui \ - autodiscoveryhostsdialog.ui + autodiscoveryhostsdialog.ui \ + appearanceoptionpage.ui include(../widgets/widgets.pri) include(../lib.pri) diff --git a/src/bench/benchlivenodeengine.cpp b/src/bench/benchlivenodeengine.cpp index 30dd5b5..02f153e 100644 --- a/src/bench/benchlivenodeengine.cpp +++ b/src/bench/benchlivenodeengine.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -110,7 +111,7 @@ void BenchLiveNodeEngine::initPlugins() //This needs to be QueuedConnection because Qt5 doesn't like it to destruct it's object while it is in a signalHandler connect(adapter, &DirectoryPreviewAdapter::loadDocument, this, [this](const QString &document) { - m_workspaceView->activateDocument(LiveDocument(document)); + m_workspaceView->activateDocument(LiveDocument::resolve(workspace(), document)); }, Qt::QueuedConnection); } diff --git a/src/bench/benchlivenodeengine.h b/src/bench/benchlivenodeengine.h index c29c6ed..1a29c2c 100644 --- a/src/bench/benchlivenodeengine.h +++ b/src/bench/benchlivenodeengine.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/bench/directorypreviewadapter.cpp b/src/bench/directorypreviewadapter.cpp index a6bda41..26bd643 100644 --- a/src/bench/directorypreviewadapter.cpp +++ b/src/bench/directorypreviewadapter.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/bench/directorypreviewadapter.h b/src/bench/directorypreviewadapter.h index f1aa497..47f7f59 100644 --- a/src/bench/directorypreviewadapter.h +++ b/src/bench/directorypreviewadapter.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/bench/dummydelegate.cpp b/src/bench/dummydelegate.cpp index 3abf723..c83305b 100644 --- a/src/bench/dummydelegate.cpp +++ b/src/bench/dummydelegate.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/bench/dummydelegate.h b/src/bench/dummydelegate.h index d74de98..dc56232 100644 --- a/src/bench/dummydelegate.h +++ b/src/bench/dummydelegate.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/bench/host.cpp b/src/bench/host.cpp index 2103e43..ffd831d 100644 --- a/src/bench/host.cpp +++ b/src/bench/host.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/bench/host.h b/src/bench/host.h index 0e7d1bb..03ac3f3 100644 --- a/src/bench/host.h +++ b/src/bench/host.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/bench/hostdiscoverymanager.cpp b/src/bench/hostdiscoverymanager.cpp index a0ad190..401dc44 100644 --- a/src/bench/hostdiscoverymanager.cpp +++ b/src/bench/hostdiscoverymanager.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/bench/hostdiscoverymanager.h b/src/bench/hostdiscoverymanager.h index 596bb46..4c1cb31 100644 --- a/src/bench/hostdiscoverymanager.h +++ b/src/bench/hostdiscoverymanager.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/bench/hostmanager.cpp b/src/bench/hostmanager.cpp index 633bfcd..947ca14 100644 --- a/src/bench/hostmanager.cpp +++ b/src/bench/hostmanager.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/bench/hostmanager.h b/src/bench/hostmanager.h index 68f241e..1aa51b9 100644 --- a/src/bench/hostmanager.h +++ b/src/bench/hostmanager.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -68,6 +69,8 @@ private slots: void addHost(int index); private: + using QListView::setModel; + QPointer<LiveHubEngine> m_engine; HostModel* m_model; diff --git a/src/bench/hostmodel.cpp b/src/bench/hostmodel.cpp index 98c102e..dc57abb 100644 --- a/src/bench/hostmodel.cpp +++ b/src/bench/hostmodel.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -84,11 +85,11 @@ QVariant HostModel::headerData(int section, Qt::Orientation orientation, int rol return QVariant(); switch (section) { - case 0: if (role == Qt::DisplayRole) return QVariant(); - case 1: if (role == Qt::DisplayRole) return QString("Name"); - case 2: if (role == Qt::DisplayRole) return QString("Version"); - case 3: if (role == Qt::DisplayRole) return QString("System"); - case 4: if (role == Qt::DisplayRole) return QString("Ip"); + case 0: if (role == Qt::DisplayRole) return QVariant(); break; + case 1: if (role == Qt::DisplayRole) return QString("Name"); break; + case 2: if (role == Qt::DisplayRole) return QString("Version"); break; + case 3: if (role == Qt::DisplayRole) return QString("System"); break; + case 4: if (role == Qt::DisplayRole) return QString("Ip"); break; } return QVariant(); diff --git a/src/bench/hostmodel.h b/src/bench/hostmodel.h index 252a52a..5c777c7 100644 --- a/src/bench/hostmodel.h +++ b/src/bench/hostmodel.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/bench/hostsoptionpage.cpp b/src/bench/hostsoptionpage.cpp index c7ac997..cb98cc2 100644 --- a/src/bench/hostsoptionpage.cpp +++ b/src/bench/hostsoptionpage.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/bench/hostsoptionpage.h b/src/bench/hostsoptionpage.h index dc829e0..6321d08 100644 --- a/src/bench/hostsoptionpage.h +++ b/src/bench/hostsoptionpage.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/bench/hostwidget.cpp b/src/bench/hostwidget.cpp index 804de9b..591560c 100644 --- a/src/bench/hostwidget.cpp +++ b/src/bench/hostwidget.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/bench/hostwidget.h b/src/bench/hostwidget.h index 7bb3366..0bceb93 100644 --- a/src/bench/hostwidget.h +++ b/src/bench/hostwidget.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/bench/httpproxyoptionpage.cpp b/src/bench/httpproxyoptionpage.cpp index 28a9867..ad025c0 100644 --- a/src/bench/httpproxyoptionpage.cpp +++ b/src/bench/httpproxyoptionpage.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/bench/httpproxyoptionpage.h b/src/bench/httpproxyoptionpage.h index 555c20c..1c09b45 100644 --- a/src/bench/httpproxyoptionpage.h +++ b/src/bench/httpproxyoptionpage.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/bench/importpathoptionpage.cpp b/src/bench/importpathoptionpage.cpp index 34fd3e1..bf6f55e 100644 --- a/src/bench/importpathoptionpage.cpp +++ b/src/bench/importpathoptionpage.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/bench/importpathoptionpage.h b/src/bench/importpathoptionpage.h index 1a7224a..38874cb 100644 --- a/src/bench/importpathoptionpage.h +++ b/src/bench/importpathoptionpage.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/bench/main.cpp b/src/bench/main.cpp index 728cf9b..5b9c2f9 100644 --- a/src/bench/main.cpp +++ b/src/bench/main.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -36,9 +37,11 @@ #include "hostmanager.h" #include "hostmodel.h" +#include "livehubengine.h" #include "options.h" #include "mainwindow.h" #include "qmllive_version.h" +#include "projectmanager.h" class Application : public QApplication { @@ -46,6 +49,7 @@ class Application : public QApplication public: static Application *create(int &argc, char **argv); + ~Application() override; protected: Application(int &argc, char **argv); @@ -53,7 +57,14 @@ protected: QString serverName() const; void setDarkStyle(); - void parseArguments(const QStringList &arguments, Options *options); + static void parseArguments(const QStringList &arguments, Options *options); + static const Options *options() { return s_options; } + +private: + static QString userName(); + +private: + static Options *s_options; }; class MasterApplication : public Application @@ -62,6 +73,7 @@ class MasterApplication : public Application public: MasterApplication(int &argc, char **argv); + ~MasterApplication(); private: void listenForArguments(); @@ -83,16 +95,18 @@ private: void forwardArguments(); }; +Options *Application::s_options = 0; + Application *Application::create(int &argc, char **argv) { setApplicationName("QmlLiveBench"); setOrganizationDomain(QLatin1String(QMLLIVE_ORGANIZATION_DOMAIN)); setOrganizationName(QLatin1String(QMLLIVE_ORGANIZATION_NAME)); - // Workaround: Cannot use QCoreApplication::arguments before app is instantiated - const bool hasNoRemoteOption = argc >= 2 && QString::fromLocal8Bit(argv[1]) == QLatin1String("--noremote"); + // Cannot instantiate the actual application yet + parseArguments(QCoreApplication(argc, argv).arguments(), s_options = new Options); - if (hasNoRemoteOption || isMaster()) + if (isMaster()) return new MasterApplication(argc, argv); else return new SlaveApplication(argc, argv); @@ -107,10 +121,19 @@ Application::Application(int &argc, char **argv) setDarkStyle(); } +Application::~Application() +{ + delete s_options, s_options = 0; +} + bool Application::isMaster() { Q_ASSERT(!applicationName().isEmpty()); Q_ASSERT(!organizationDomain().isEmpty() || !organizationName().isEmpty()); + Q_ASSERT(s_options); + + if (s_options->noRemote()) + return true; static QSharedMemory *lock = 0; static bool retv = false; @@ -118,9 +141,10 @@ bool Application::isMaster() if (lock != 0) return retv; - const QString key = QString::fromLatin1("%1.%2-lock") + const QString key = QString::fromLatin1("%1.%2-%3-lock") .arg(organizationDomain().isEmpty() ? organizationName() : organizationDomain()) - .arg(applicationName()); + .arg(applicationName()) + .arg(userName()); lock = new QSharedMemory(key, qApp); @@ -145,9 +169,10 @@ QString Application::serverName() const Q_ASSERT(!applicationName().isEmpty()); Q_ASSERT(!organizationDomain().isEmpty() || !organizationName().isEmpty()); - return QString::fromLatin1("%1.%2-app") + return QString::fromLatin1("%1.%2-%3-app") .arg(organizationDomain().isEmpty() ? organizationName() : organizationDomain()) - .arg(applicationName()); + .arg(applicationName()) + .arg(userName()); } void Application::setDarkStyle() @@ -199,12 +224,16 @@ void Application::parseArguments(const QStringList &arguments, Options *options) "(implies --remoteonly)", "name"); parser.addOption(probeHostOption); QCommandLineOption noRemoteOption("noremote", "do not try to talk to a running bench, do not listen for remote " - "connections. It MUST BE the VERY FIRST argument on command line."); + "connections."); parser.addOption(noRemoteOption); QCommandLineOption remoteOnlyOption("remoteonly", "talk to a running bench, do nothing if none is running."); parser.addOption(remoteOnlyOption); QCommandLineOption pingOption("ping", "just check if there is a bench running and accepting remote connections."); parser.addOption(pingOption); + QCommandLineOption maxWatchesOption("maxdirwatch", "limit the number of directories to watch for changes", "number", QString::number(options->maximumWatches())); + parser.addOption(maxWatchesOption); + QCommandLineOption projectOption("project", "loads project document .qmllive containing workspace path, imports paths, main document in JSON format"); + parser.addOption(projectOption); parser.process(arguments); @@ -231,6 +260,15 @@ void Application::parseArguments(const QStringList &arguments, Options *options) parser.showHelp(-1); } + if (parser.isSet(maxWatchesOption)) { + bool ok; + int value = parser.value(maxWatchesOption).toInt(&ok); + if (!ok) { + qWarning() << "Invalid argument to --maxdirwatch option"; + parser.showHelp(-1); + } + options->setMaximumWatches(value); + } options->setPluginPath(parser.value(pluginPathOption)); options->setImportPaths(parser.values(importPathOption)); @@ -263,12 +301,16 @@ void Application::parseArguments(const QStringList &arguments, Options *options) options->setHostsToRemove(parser.values(rmHostOption)); options->setHostsToProbe(parser.values(probeHostOption)); + if (parser.isSet(projectOption)){ + options->setProject(parser.value(projectOption)); + } + const QStringList positionalArguments = parser.positionalArguments(); if (positionalArguments.count() >= 1) { QString argument = positionalArguments.value(0); QFileInfo fi(argument); if (argument.endsWith(".qml")) { - qDebug() << "First argument ends with \".qml\". Assuming it is a file."; + qInfo() << "First argument ends with \".qml\". Assuming it is a file."; if (!fi.exists() || !fi.isFile()) { qWarning() << "Document does not exist or is not a file: " << fi.absoluteFilePath(); parser.showHelp(-1); @@ -276,12 +318,17 @@ void Application::parseArguments(const QStringList &arguments, Options *options) options->setWorkspace(fi.absolutePath()); options->setActiveDocument(LiveDocument(fi.absoluteFilePath())); } else { - qDebug() << "First argument does not ending with \".qml\". Assuming it is a workspace."; - if (!fi.exists() || !fi.isDir()) { - qWarning() << "Workspace does not exist or is not a directory: " << fi.absoluteFilePath(); - parser.showHelp(-1); + if (argument.endsWith(".qmllive") && parser.isSet(projectOption)){ + qInfo() << "First argument is ending with \".qmllive\". Assuming it is a project."; + options->setProject(fi.absoluteFilePath()); + } else { + qInfo() << "First argument does not ending with \".qml\". Assuming it is a workspace."; + if (!fi.exists() || !fi.isDir()) { + qWarning() << "Workspace does not exist or is not a directory: " << fi.absoluteFilePath(); + parser.showHelp(-1); + } + options->setWorkspace(fi.absoluteFilePath()); } - options->setWorkspace(fi.absoluteFilePath()); } } if (positionalArguments.count() == 2) { @@ -302,6 +349,22 @@ void Application::parseArguments(const QStringList &arguments, Options *options) } } +QString Application::userName() +{ + QString retv; + +#if defined(Q_OS_UNIX) + retv = QString::fromLocal8Bit(qgetenv("USER")); +#elif defined(Q_OS_WIN) + retv = QString::fromLocal8Bit(qgetenv("USERNAME")); +#endif + + if (retv.isEmpty()) + qWarning("Failed to determine system user name"); + + return retv; +} + /* * class MasterApplication */ @@ -310,31 +373,33 @@ MasterApplication::MasterApplication(int &argc, char **argv) : Application(argc, argv) , m_window(new MainWindow) { - Options options; - parseArguments(arguments(), &options); - - if (options.ping()) { + if (options()->ping()) { QTimer::singleShot(0, [] { QCoreApplication::exit(1); }); return; } - if (options.remoteOnly()) { + if (options()->remoteOnly()) { QTimer::singleShot(0, this, &QCoreApplication::quit); return; } - applyOptions(options); + applyOptions(*options()); - if (options.hasNoninteractiveOptions()) { + if (options()->hasNoninteractiveOptions()) { QTimer::singleShot(0, this, &QCoreApplication::quit); } else { m_window->init(); m_window->show(); - if (!options.noRemote()) + if (!options()->noRemote()) listenForArguments(); } } +MasterApplication::~MasterApplication() +{ + delete m_window; +} + void MasterApplication::listenForArguments() { QLocalServer *server = new QLocalServer(this); @@ -390,6 +455,21 @@ void MasterApplication::listenForArguments() void MasterApplication::applyOptions(const Options &options) { + LiveHubEngine::setMaximumWatches(options.maximumWatches()); + + if (!options.project().isEmpty()) { + if (m_window->isInitialized()) + m_window->setProject(options.project()); + else { + ProjectManager pr; + if (pr.read(options.project())) { + m_window->setWorkspace(pr.workspace()); + m_window->setImportPaths(pr.imports()); + m_window->activateDocument(LiveDocument(pr.mainDocument())); + } + } + } + if (!options.workspace().isEmpty()) m_window->setWorkspace(QDir(options.workspace()).absolutePath(), false); @@ -474,18 +554,15 @@ void MasterApplication::applyOptions(const Options &options) SlaveApplication::SlaveApplication(int &argc, char **argv) : Application(argc, argv) { - Options options; - parseArguments(arguments(), &options); - - if (options.ping()) { + if (options()->ping()) { QTimer::singleShot(0, &QCoreApplication::quit); return; } - if (!options.remoteOnly() && !options.hasNoninteractiveOptions()) + if (!options()->remoteOnly() && !options()->hasNoninteractiveOptions()) qInfo() << "Another instance running. Activating..."; - warnAboutIgnoredOptions(options); + warnAboutIgnoredOptions(*options()); forwardArguments(); } diff --git a/src/bench/mainwindow.cpp b/src/bench/mainwindow.cpp index 61924aa..9f41c38 100644 --- a/src/bench/mainwindow.cpp +++ b/src/bench/mainwindow.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -48,7 +49,49 @@ #include "allhostswidget.h" #include "hostdiscoverymanager.h" #include "options.h" +#include "newprojectwizard.h" +#include "projectmanager.h" +class ErrorBar : public QFrame +{ + Q_OBJECT + +public: + ErrorBar(QWidget *parent = nullptr) + : QFrame(parent) + { + setFrameShape(QFrame::StyledPanel); + setAutoFillBackground(true); + QPalette p = palette(); + p.setColor(QPalette::Window, Qt::red); + setPalette(p); + + auto layout = new QHBoxLayout(this); + layout->setContentsMargins(4, 4, 4, 4); + + m_label = new QLabel; + m_label->setWordWrap(true); + layout->addWidget(m_label); + + auto button = new QToolButton; + button->setAutoRaise(true); + button->setIcon(QIcon(":images/refresh.svg")); + connect(button, &QAbstractButton::clicked, this, &ErrorBar::retry); + layout->addWidget(button); + } + + void setError(const QString &errorString) + { + m_label->setText(errorString); + setVisible(!errorString.isEmpty()); + } + +signals: + void retry(); + +private: + QLabel *m_label; +}; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) @@ -61,6 +104,8 @@ MainWindow::MainWindow(QWidget *parent) , m_allHosts(new AllHostsWidget(this)) , m_hub(new LiveHubEngine(this)) , m_node(new BenchLiveNodeEngine(this)) + , m_newProjectWizard(new NewProjectWizard(this)) + , m_projectManager(new ProjectManager(this)) { setupContent(); setupMenuBar(); @@ -88,6 +133,7 @@ MainWindow::MainWindow(QWidget *parent) connect(m_allHosts, &AllHostsWidget::refreshAll, m_hostManager, &HostManager::refreshAll); connect(m_hostManager, &HostManager::logWidgetAdded, this, &MainWindow::onLogWidgetAdded); connect(m_hostManager, &HostManager::openHostConfig, this, &MainWindow::openPreferences); + connect(m_newProjectWizard, &NewProjectWizard::accepted, this, &MainWindow::newProject); m_qmlDefaultimportList = m_node->qmlEngine()->importPathList(); } @@ -132,9 +178,42 @@ void MainWindow::setupWorkspaceView() { m_workspaceDock = new QDockWidget("Workspace", this); m_workspaceDock->setObjectName("workspace"); - m_workspaceDock->setWidget(m_workspace); m_workspaceDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); m_workspaceDock->setFeatures(QDockWidget::AllDockWidgetFeatures); + + auto contents = new QWidget; + auto layout = new QVBoxLayout(contents); + layout->setContentsMargins(1, 1, 1, 1); + layout->setSpacing(1); + + auto errorBar = new ErrorBar; + layout->addWidget(errorBar); + + auto updateErrorBar = [this, errorBar]() { + QString error; + switch (m_hub->error()) { + case LiveHubEngine::NoError: + break; + case LiveHubEngine::WatcherMaximumReached: + error = tr("Unable to monitor file changes: The configured limit of %1 directories was exceeded.") + .arg(LiveHubEngine::maximumWatches()); + break; + case LiveHubEngine::WatcherSystemError: + error = tr("Unable to monitor file changes. System limit exceeded?"); + break; + } + errorBar->setError(error); + }; + updateErrorBar(); + connect(m_hub, &LiveHubEngine::errorChanged, errorBar, updateErrorBar); + + connect(errorBar, &ErrorBar::retry, this, [this]() { + m_hub->setWorkspace(m_hub->workspace()); + }); + + layout->addWidget(m_workspace); + + m_workspaceDock->setWidget(contents); addDockWidget(Qt::LeftDockWidgetArea, m_workspaceDock); } @@ -177,10 +256,24 @@ void MainWindow::setupMenuBar() { QMenu *file = menuBar()->addMenu(tr("&File")); #if QT_VERSION < QT_VERSION_CHECK(5, 6, 0) - m_openWorkspace = file->addAction(QIcon::fromTheme("folder-open"), tr("&Open Workspace..."), this, SLOT(openWorkspace()), QKeySequence::Open); + m_createProject = file->addAction(QIcon::fromTheme("folder-new"), tr("&New Project"), this, SLOT(newProject()), QKeySequence::New); +#else + m_createProject = file->addAction(QIcon::fromTheme("folder-new"), tr("&New Project"), + this, &MainWindow::newProjectWizard, QKeySequence::New); +#endif + +#if QT_VERSION < QT_VERSION_CHECK(5, 6, 0) + m_openProject = file->addAction(QIcon::fromTheme("folder-open"), tr("&Open Project..."), this, SLOT(openProject()), QKeySequence::Open); +#else + m_openProject = file->addAction(QIcon::fromTheme("folder-open"), tr("&Open Project..."), + this, &MainWindow::openProject, QKeySequence::Open); +#endif + +#if QT_VERSION < QT_VERSION_CHECK(5, 6, 0) + m_openWorkspace = file->addAction(QIcon::fromTheme("folder-open"), tr("&Open Workspace..."), this, SLOT(openWorkspace()), QKeySequence("Ctrl+W")); #else m_openWorkspace = file->addAction(QIcon::fromTheme("folder-open"), tr("&Open Workspace..."), - this, &MainWindow::openWorkspace, QKeySequence::Open); + this, &MainWindow::openWorkspace, QKeySequence("Ctrl+W")); #endif m_recentMenu = file->addMenu(QIcon::fromTheme("document-open-recent"), "&Recent"); m_recentMenu->setEnabled(false); @@ -300,6 +393,8 @@ void MainWindow::init() m_hostModel->restoreFromSettings(&s); restoreState(s.value("windowState").toByteArray()); + m_workspace->restoreFromSettings(&s); + m_initialized = true; } @@ -341,6 +436,8 @@ void MainWindow::setupToolBar() m_toolBar = addToolBar("ToolBar"); m_toolBar->setObjectName("toolbar"); m_toolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + m_toolBar->addAction(m_createProject); + m_toolBar->addAction(m_openProject); m_toolBar->addAction(m_openWorkspace); m_toolBar->addSeparator(); m_toolBar->addAction(m_refresh); @@ -413,6 +510,11 @@ void MainWindow::setStaysOnTop(bool enabled) stayOnTop(); } +void MainWindow::setProject(const QString &projectFile) +{ + openProjectFile(projectFile); +} + void MainWindow::closeEvent(QCloseEvent *event) { writeSettings(); @@ -453,6 +555,7 @@ void MainWindow::updateWindowTitle() void MainWindow::openPreferences(Host *host) { OptionsDialog dialog; + connect(&dialog, &OptionsDialog::hideNonQMLFiles, m_workspace, &WorkspaceView::hideNonQMLFiles); dialog.setHostModel(m_hostModel); dialog.setDiscoveredHostsModel(m_discoveryManager->discoveredHostsModel()); @@ -517,3 +620,71 @@ void MainWindow::stayOnTop() } show(); } + +void MainWindow::openProject() +{ + QString filter = tr("QmlLive (*.qmllive);; All files (*.*)"); + QString path = QFileDialog::getOpenFileName(this, "Open Project", filter, filter); + if (path.isEmpty()) { + return; + } + openProjectFile(path); +} + +void MainWindow::openProjectFile(const QString &path) +{ + if (m_projectManager->read(path)) + { + QStringList paths; + QSettings s; + int count = s.beginReadArray("imports"); + for (int i=0; i<count; i++) { + s.setArrayIndex(i); + paths.append(s.value("path").toString()); + } + s.endArray(); + paths.append(m_projectManager->imports()); + paths.removeDuplicates(); + + //write Application settings + s.beginWriteArray("imports"); + for (int i = 0; i < paths.count(); i++) { + s.setArrayIndex(i); + s.setValue("path", paths.at(i)); + } + s.endArray(); + + setImportPaths(paths); + QString path = QDir(m_projectManager->projectLocation()).absoluteFilePath(m_projectManager->workspace()); + setWorkspace(path); + activateDocument(LiveDocument(m_projectManager->mainDocument())); + } + else { + qWarning() << "Unable to read project document: "<<path; + } +} + +void MainWindow::newProjectWizard() +{ + if (!m_newProjectWizard) { + m_newProjectWizard = new NewProjectWizard(this); + } else { + m_newProjectWizard->restart(); + } + m_newProjectWizard->show(); +} + +void MainWindow::newProject() +{ + m_projectManager->setImports(m_newProjectWizard->imports()); + m_projectManager->setMainDocument(m_newProjectWizard->mainDocument()); + m_projectManager->setWorkspace(m_newProjectWizard->workspace()); + m_projectManager->create(m_newProjectWizard->projectName()); + + setImportPaths(m_newProjectWizard->imports()); + QString path = QDir(m_projectManager->projectLocation()).absoluteFilePath(m_newProjectWizard->workspace()); + setWorkspace(path); + activateDocument(LiveDocument(m_newProjectWizard->mainDocument())); +} + +#include "mainwindow.moc" diff --git a/src/bench/mainwindow.h b/src/bench/mainwindow.h index 4a7e8f1..7dc6588 100644 --- a/src/bench/mainwindow.h +++ b/src/bench/mainwindow.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -50,19 +51,23 @@ class AllHostsWidget; class Host; class HostDiscoveryManager; class Options; +class NewProjectWizard; +class ProjectManager; + QT_FORWARD_DECLARE_CLASS(QToolBar); class MainWindow : public QMainWindow { Q_OBJECT public: - explicit MainWindow(QWidget *parent = 0); + explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); void activateDocument(const LiveDocument &path); void setWorkspace(const QString& path, bool activateRootPath = true); void setPluginPath(const QString& path); void setImportPaths(const QStringList& pathList); void setStaysOnTop(bool enabled); + void setProject(const QString& projectFile); void init(); bool isInitialized() const { return m_initialized; } @@ -81,6 +86,7 @@ private: void setupMenuBar(); void writeSettings(); void resetImportPaths(); + void openProjectFile(const QString& path); private slots: void resizeToFit(); void takeSnapshot(); @@ -88,10 +94,13 @@ private slots: void openWorkspace(); void logQuitEvent(); void updateWindowTitle(); - void openPreferences(Host *host = 0); + void openPreferences(Host *host = nullptr); void openRecentFolder(); void clearRecentFolder(); void stayOnTop(); + void openProject(); + void newProjectWizard(); + void newProject(); void onActiveWindowChanged(QQuickWindow *activeWindow); @@ -126,4 +135,8 @@ private: QAction *m_clipRootObject; QToolBar* m_toolBar; QStringList m_qmlDefaultimportList; + QAction *m_openProject; + QAction *m_createProject; + NewProjectWizard *m_newProjectWizard; + ProjectManager *m_projectManager; }; diff --git a/src/bench/newprojectwizard.cpp b/src/bench/newprojectwizard.cpp new file mode 100644 index 0000000..74c7f33 --- /dev/null +++ b/src/bench/newprojectwizard.cpp @@ -0,0 +1,403 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QmlLive tool. +** +** $QT_BEGIN_LICENSE:GPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite licenses may use +** this file in accordance with the commercial license agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and The Qt Company. For +** licensing terms and conditions see https://www.qt.io/terms-conditions. +** For further information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: GPL-3.0 +** +****************************************************************************/ + +#include "newprojectwizard.h" + +#include <QGridLayout> +#include <QListWidget> +#include <QPushButton> +#include <QFileDialog> +#include "livedocument.h" + +const QString QmlLiveProjectsLocation(QDir(QDir().homePath()).absoluteFilePath("QMLLive")); + +NewProjectWizard::NewProjectWizard(QWidget *parent) + : QWizard(parent) + , m_importListWidget(nullptr) + , m_projectPage(new ProjectPage()) + , m_workspacePage(new WorkspacePage()) + , m_mainDocumentPage(new MainDocumentPage()) + , m_projectFileDir(nullptr) +{ + setWizardStyle(QWizard::ClassicStyle); + setOptions(QWizard::NoBackButtonOnStartPage); + addPage(m_projectPage); + addPage(m_workspacePage); + addPage(createImportsPage()); + addPage(m_mainDocumentPage); + + connect(m_workspacePage, &WorkspacePage::updateWorkspace, m_mainDocumentPage, &MainDocumentPage::updateWorkspace); + connect(m_projectPage, &ProjectPage::updateProjectDir, m_workspacePage, &WorkspacePage::onUpdateProjectDir); + connect(m_projectPage, &ProjectPage::updateProjectDir, m_mainDocumentPage, &MainDocumentPage::onUpdateProjectDir); + connect(m_projectPage, &ProjectPage::updateProjectDir, this, &NewProjectWizard::onUpdateProjectDir); +} + +MainDocumentPage::MainDocumentPage(QWidget *parent) + : QWizardPage (parent) + , m_workspace(nullptr) + , m_mainDocumentField(new QLineEdit) + , m_projectFileDir(nullptr) +{ + setTitle("Main Document"); + + QVBoxLayout *vbox = new QVBoxLayout; + + QLabel *hintlabel = new QLabel("Please select main QML document to load initially."); + hintlabel->setWordWrap(true); + hintlabel->setAlignment(Qt::AlignJustify); + vbox->addWidget(hintlabel); + + QGridLayout *layout = new QGridLayout; + + QLabel *label = new QLabel("Main document: "); + layout->addWidget(label, 1, 0); + + m_mainDocumentField = new QLineEdit; + registerField("mainDocument*", m_mainDocumentField); + layout->addWidget(m_mainDocumentField, 1, 1); + + QPushButton *button = new QPushButton("Select"); + layout->addWidget(button, 1, 2); + connect(button, SIGNAL(clicked()), this, SLOT(selectDocument())); + + m_warningLabel = new QLabel; + QPalette palette = m_warningLabel->palette(); + palette.setColor(m_warningLabel->backgroundRole(), Qt::yellow); + palette.setColor(m_warningLabel->foregroundRole(), Qt::yellow); + m_warningLabel->setPalette(palette); + layout->addWidget(m_warningLabel, 2, 0, 1, 3, Qt::AlignTop); + + layout->setColumnStretch(1, 1); + layout->setRowStretch(1, 1); + vbox->addLayout(layout); + setLayout(vbox); + +} + +QString MainDocumentPage::mainDocument() const +{ + if (m_mainDocumentField) { + return m_mainDocumentField->text(); + } + return ""; +} + +void MainDocumentPage::onUpdateProjectDir(const QString &path) +{ + if (m_projectFileDir == nullptr){ + m_projectFileDir = new QDir(path); + } + else { + m_projectFileDir->setPath(path); + } +} + +void MainDocumentPage::selectDocument() +{ + m_warningLabel->setText(""); + QString filter = tr("QML (*.qml);; All files (*.*)"); + QString path = QFileDialog::getOpenFileName(this, "Select File", *m_workspace, filter); + QString file = QDir(m_projectFileDir->absoluteFilePath(*m_workspace)).relativeFilePath(path); + + if (!file.isEmpty() && m_mainDocumentField) { + m_mainDocumentField->setText(file); + } +} + +bool MainDocumentPage::validatePage() +{ + if (QFileInfo(QDir(m_projectFileDir->absoluteFilePath(*m_workspace)), mainDocument()).exists()) { + m_warningLabel->setText(""); + return true; + } else { + m_warningLabel->setText("The file you entered does not exist or is located not in the workspace folder."); + return false; + } +} + +void MainDocumentPage::updateWorkspace(const QString &workspace) +{ + if (m_workspace == nullptr){ + m_workspace = new QString(workspace); + } + else { + *m_workspace = workspace; + } +} + + +WorkspacePage::WorkspacePage(QWidget *parent) + : QWizardPage (parent) + , m_workspaceField(new QLineEdit) + , m_warningLabel(new QLabel) + , m_projectFileDir(nullptr) +{ + setTitle("Select Workspace"); + QVBoxLayout *vbox = new QVBoxLayout; + + QLabel *hintlabel = new QLabel("Please select workspace folder to watch for updates of edited QML files. " + "The path should be relative to the project file location."); + hintlabel->setWordWrap(true); + hintlabel->setAlignment(Qt::AlignJustify); + vbox->addWidget(hintlabel); + + QGridLayout *layout = new QGridLayout; + + QLabel *label = new QLabel("Workspace: "); + layout->addWidget(label, 1, 0); + + m_workspaceField = new QLineEdit; + registerField("workspace*", m_workspaceField); + layout->addWidget(m_workspaceField, 1, 1); + + QPushButton *button = new QPushButton("Select"); + layout->addWidget(button, 1, 2); + connect(button, SIGNAL(clicked()), this, SLOT(selectWorkspacePath())); + + m_warningLabel = new QLabel; + QPalette palette = m_warningLabel->palette(); + palette.setColor(m_warningLabel->backgroundRole(), Qt::yellow); + palette.setColor(m_warningLabel->foregroundRole(), Qt::yellow); + m_warningLabel->setPalette(palette); + layout->addWidget(m_warningLabel, 2, 0, 1, 3, Qt::AlignTop); + + layout->setColumnStretch(1, 1); + layout->setRowStretch(1, 1); + vbox->addLayout(layout); + setLayout(vbox); +} + +QString WorkspacePage::workspace() const +{ + if (m_workspaceField) { + return m_workspaceField->text(); + } + return ""; +} + +void WorkspacePage::selectWorkspacePath() +{ + m_warningLabel->setText(""); + QString path = QFileDialog::getExistingDirectory(this, "Select Workspace"); + QString workspace = m_projectFileDir->relativeFilePath(path); + if (!workspace.isEmpty() && m_workspaceField) { + m_workspaceField->setText(workspace); + } +} + +bool WorkspacePage::validatePage() +{ + if (m_projectFileDir->exists(workspace())) { + m_warningLabel->setText(""); + emit updateWorkspace(workspace()); + return true; + } else { + m_warningLabel->setText("The path you entered does not exist."); + return false; + } +} + +void WorkspacePage::onUpdateProjectDir(const QString &path) +{ + if (m_projectFileDir == nullptr){ + m_projectFileDir = new QDir(path); + } + else { + m_projectFileDir->setPath(path); + } +} + +QWizardPage *NewProjectWizard::createImportsPage() +{ + QWizardPage *page = new QWizardPage; + page->setTitle("Imports"); + QGridLayout *layout = new QGridLayout; + + m_importListWidget = new QListWidget; + layout->addWidget(m_importListWidget, 0, 0, 4, 1); + + QPushButton *add = new QPushButton("Add"); + connect(add, SIGNAL(clicked()), this, SLOT(addImportPath())); + layout->addWidget(add, 0, 1); + + QPushButton *edit = new QPushButton("Edit"); + connect(edit, SIGNAL(clicked()), this, SLOT(editImportPath())); + layout->addWidget(edit, 1, 1); + + QPushButton *remove = new QPushButton("Remove"); + connect(remove, SIGNAL(clicked()), this, SLOT(removeImportPath())); + layout->addWidget(remove, 2, 1); + + layout->setRowStretch(4, 1); + page->setLayout(layout); + return page; +} + +ProjectPage::ProjectPage(QWidget *parent) + : QWizardPage (parent) + , m_projectField(new QLineEdit) + , m_dirField(new QLineEdit) +{ + setTitle("Project Name"); + QVBoxLayout *vbox = new QVBoxLayout; + + QLabel *hintlabel = new QLabel("This wizard generates a QmlLive project. The QmlLive project file shall describe the " + "common options for a QmlLiveBench by specifying the workspace folder, the main document " + "and the import paths relative to the project document location."); + hintlabel->setWordWrap(true); + hintlabel->setAlignment(Qt::AlignJustify); + vbox->addWidget(hintlabel); + + QGridLayout *layout = new QGridLayout; + + QLabel *label = new QLabel("Project name: "); + layout->addWidget(label, 1, 0); + + m_projectField = new QLineEdit; + registerField("projectName*", m_projectField); + m_projectField->setPlaceholderText("MyQmlLiveProject"); + layout->addWidget(m_projectField, 1, 1); + + QLabel *dirlabel = new QLabel("Create in: "); + layout->addWidget(dirlabel, 2, 0); + + layout->addWidget(m_dirField, 2, 1); + m_dirField->setText(QmlLiveProjectsLocation); + + QPushButton *button = new QPushButton("Select"); + layout->addWidget(button, 2, 2); + connect(button, &QPushButton::clicked, this, &ProjectPage::selectProjectPath); + + layout->setColumnStretch(1, 1); + layout->setRowStretch(1, 1); + vbox->addLayout(layout); + setLayout(vbox); +} + +QString ProjectPage::projectName() const +{ + if (m_projectField) { + if (m_dirField->text().isEmpty()) + return m_projectField->text(); + else { + return QDir(m_dirField->text()).absoluteFilePath(m_projectField->text()); + } + } + return ""; +} + +bool ProjectPage::validatePage() +{ + QDir dir(m_dirField->text()); + if (QDir().mkpath(m_dirField->text())) { + emit updateProjectDir(m_dirField->text()); + return true; + } + else { + qWarning()<< "Unable to create directory: "<< m_dirField->text(); + return false; + } +} + +void ProjectPage::selectProjectPath() +{ + QString projectPath = QFileDialog::getExistingDirectory(this, "Create in"); + if (!projectPath.isEmpty() && m_dirField) { + m_dirField->setText(projectPath); + } +} + +QString NewProjectWizard::mainDocument() const +{ + return m_mainDocumentPage->mainDocument(); +} + +QString NewProjectWizard::workspace() const +{ + return m_workspacePage->workspace(); +} + +QStringList NewProjectWizard::imports() const +{ + QStringList list; + if (m_importListWidget) { + for (int i = 0; i < m_importListWidget->count(); i++) { + list.append(m_importListWidget->takeItem(i)->text()); + } + } + + return list; +} + +QString NewProjectWizard::projectName() const +{ + return m_projectPage->projectName(); +} + +void NewProjectWizard::addImportPath() +{ + QString path = QFileDialog::getExistingDirectory(this, "Add Import Path"); + if (path.isEmpty()) { + return; + } + QString relativepath = m_projectFileDir->relativeFilePath(path); + QListWidgetItem *item = new QListWidgetItem(relativepath); + item->setFlags(item->flags () | Qt::ItemIsEditable); + m_importListWidget->addItem(item); + +} + +void NewProjectWizard::editImportPath() +{ + QListWidgetItem *item = m_importListWidget->currentItem(); + if (item) { + m_importListWidget->editItem(item); + } + +} + +void NewProjectWizard::removeImportPath() +{ + QListWidgetItem *item = m_importListWidget->currentItem(); + if (item) { + delete item; + } +} + +void NewProjectWizard::onUpdateProjectDir(const QString &path) +{ + if (m_projectFileDir == nullptr){ + m_projectFileDir = new QDir(path); + } + else { + m_projectFileDir->setPath(path); + } +} diff --git a/src/bench/newprojectwizard.h b/src/bench/newprojectwizard.h new file mode 100644 index 0000000..dcdc0cc --- /dev/null +++ b/src/bench/newprojectwizard.h @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QmlLive tool. +** +** $QT_BEGIN_LICENSE:GPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite licenses may use +** this file in accordance with the commercial license agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and The Qt Company. For +** licensing terms and conditions see https://www.qt.io/terms-conditions. +** For further information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: GPL-3.0 +** +****************************************************************************/ + +#pragma once + +#include <QWizard> +#include <QWizardPage> +#include <QLineEdit> +#include <QListWidget> +#include <QLabel> +#include <QDir> + +class ProjectPage : public QWizardPage +{ + Q_OBJECT + +public: + ProjectPage(QWidget *parent = nullptr); + QString projectName() const; + bool validatePage() override; + +signals: + void updateProjectDir(const QString &path); + +private slots: + void selectProjectPath(); +private: + QLineEdit *m_projectField; + QLineEdit *m_dirField; +}; + +class WorkspacePage : public QWizardPage +{ + Q_OBJECT + +public: + WorkspacePage(QWidget *parent = nullptr); + QString workspace() const; + bool validatePage() override; + +signals: + void updateWorkspace(const QString& workspace); + +private slots: + void selectWorkspacePath(); + +public slots: + void onUpdateProjectDir(const QString &path); + +private: + QLineEdit *m_workspaceField; + QLabel *m_warningLabel; + QDir *m_projectFileDir; +}; + +class MainDocumentPage : public QWizardPage +{ + Q_OBJECT + +public: + MainDocumentPage(QWidget *parent = nullptr); + QString mainDocument() const; + bool validatePage() override; + +private slots: + void selectDocument(); +public slots: + void updateWorkspace(const QString& workspace); + void onUpdateProjectDir(const QString &path); + +private: + QLineEdit *m_mainDocumentField; + QLabel *m_warningLabel; + QString *m_workspace; + QDir *m_projectFileDir; +}; + +class NewProjectWizard : public QWizard +{ + Q_OBJECT +public: + explicit NewProjectWizard(QWidget *parent = 0); + QWizardPage* createMainDocumentPage(); + QWizardPage* createWorkspacePage(); + QWizardPage* createImportsPage(); + QWizardPage* createProjectPage(); + + QString mainDocument() const; + QString workspace() const; + QStringList imports() const; + QString projectName() const; + +private slots: + void addImportPath(); + void editImportPath(); + void removeImportPath(); + +public slots: + void onUpdateProjectDir(const QString &path); + +private: + QListWidget *m_importListWidget; + ProjectPage *m_projectPage; + WorkspacePage *m_workspacePage; + MainDocumentPage *m_mainDocumentPage; + QDir *m_projectFileDir; +}; diff --git a/src/bench/options.cpp b/src/bench/options.cpp index 5baedc2..d6d866b 100644 --- a/src/bench/options.cpp +++ b/src/bench/options.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -37,6 +38,8 @@ Options::Options(QObject *parent) , m_remoteOnly(false) , m_ping(false) , m_stayOnTop(false) + , m_maximumWatches(100) + , m_project("") { } @@ -174,3 +177,23 @@ void Options::setHostsToProbe(const QStringList &hostNames) { m_hostsToProbe = hostNames; } + +int Options::maximumWatches() const +{ + return m_maximumWatches; +} + +void Options::setMaximumWatches(int maximumWatches) +{ + m_maximumWatches = maximumWatches; +} + +QString Options::project() const +{ + return m_project; +} + +void Options::setProject(const QString &project) +{ + m_project = project; +} diff --git a/src/bench/options.h b/src/bench/options.h index e7c84bd..14ed97c 100644 --- a/src/bench/options.h +++ b/src/bench/options.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -86,6 +87,12 @@ public: QStringList hostsToProbe() const; void setHostsToProbe(const QStringList &hostNames); + int maximumWatches() const; + void setMaximumWatches(int maximumWatches); + + QString project() const; + void setProject(const QString &project); + private: bool m_noRemote; bool m_remoteOnly; @@ -98,5 +105,7 @@ private: QList<HostOptions> m_hostsToAdd; QStringList m_hostsToRemove; QStringList m_hostsToProbe; + int m_maximumWatches; + QString m_project; }; diff --git a/src/bench/optionsdialog.cpp b/src/bench/optionsdialog.cpp index 00c5898..9ad1360 100644 --- a/src/bench/optionsdialog.cpp +++ b/src/bench/optionsdialog.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -34,6 +35,7 @@ #include "httpproxyoptionpage.h" #include "importpathoptionpage.h" #include "hostsoptionpage.h" +#include "appearanceoptionpage.h" OptionsDialog::OptionsDialog(QWidget *parent) : QDialog(parent) @@ -41,6 +43,7 @@ OptionsDialog::OptionsDialog(QWidget *parent) , m_httpProxyForm(new HttpProxyOptionPage(this)) , m_importPathsForm(new ImportPathOptionPage(this)) , m_hostsForm(new HostsOptionsPage(this)) + , m_appearanceForm(new AppearanceOptionPage(this)) { ui->setupUi(this); @@ -60,8 +63,14 @@ OptionsDialog::OptionsDialog(QWidget *parent) item->setData(Qt::UserRole, index); ui->optionsView->addItem(item); + item = new QListWidgetItem("Appearance"); + index = ui->optionsStack->addWidget(m_appearanceForm); + item->setData(Qt::UserRole, index); + ui->optionsView->addItem(item); + connect(ui->optionsView, &QListWidget::currentItemChanged, this, &OptionsDialog::optionSelected); + connect(m_appearanceForm, &AppearanceOptionPage::hideNonQMLFiles, this, &OptionsDialog::hideNonQMLFiles); } OptionsDialog::~OptionsDialog() @@ -96,6 +105,7 @@ void OptionsDialog::accept() m_httpProxyForm->apply(); m_importPathsForm->apply(); m_hostsForm->apply(); + m_appearanceForm->apply(); QDialog::accept(); } @@ -105,3 +115,4 @@ void OptionsDialog::reject() } + diff --git a/src/bench/optionsdialog.h b/src/bench/optionsdialog.h index b4ea625..33e02bd 100644 --- a/src/bench/optionsdialog.h +++ b/src/bench/optionsdialog.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -45,6 +46,7 @@ class ImportPathOptionPage; class HostsOptionsPage; class HostModel; class Host; +class AppearanceOptionPage; class OptionsDialog : public QDialog { @@ -59,6 +61,9 @@ public: void openHostConfig(Host* host); +signals: + void hideNonQMLFiles(bool hide); + private slots: void optionSelected(QListWidgetItem* current); void accept(); @@ -69,4 +74,5 @@ private: HttpProxyOptionPage *m_httpProxyForm; ImportPathOptionPage *m_importPathsForm; HostsOptionsPage *m_hostsForm; + AppearanceOptionPage *m_appearanceForm; }; diff --git a/src/bench/previewimageprovider.cpp b/src/bench/previewimageprovider.cpp index 6f35874..d53ce69 100644 --- a/src/bench/previewimageprovider.cpp +++ b/src/bench/previewimageprovider.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/bench/previewimageprovider.h b/src/bench/previewimageprovider.h index 289926a..bccfc70 100644 --- a/src/bench/previewimageprovider.h +++ b/src/bench/previewimageprovider.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/bench/qmlpreviewadapter.cpp b/src/bench/qmlpreviewadapter.cpp index ac5415e..ff41bad 100644 --- a/src/bench/qmlpreviewadapter.cpp +++ b/src/bench/qmlpreviewadapter.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -62,7 +63,7 @@ QImage QmlPreviewAdapter::preview(const QString &path, const QSize &requestedSiz } static const QString program = QCoreApplication::applicationDirPath() + -#ifdef Q_OS_WINDOWS +#ifdef Q_OS_WIN QStringLiteral("/previewGenerator.exe"); #else QStringLiteral("/../libexec/qmllive/previewGenerator"); diff --git a/src/bench/qmlpreviewadapter.h b/src/bench/qmlpreviewadapter.h index 05fcd62..bcf0ec9 100644 --- a/src/bench/qmlpreviewadapter.h +++ b/src/bench/qmlpreviewadapter.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/contentadapterinterface.h b/src/contentadapterinterface.h index 7903dc5..520e1ee 100644 --- a/src/contentadapterinterface.h +++ b/src/contentadapterinterface.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/contentpluginfactory.cpp b/src/contentpluginfactory.cpp index 5b5e3ec..ca8a5b9 100644 --- a/src/contentpluginfactory.cpp +++ b/src/contentpluginfactory.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/contentpluginfactory.h b/src/contentpluginfactory.h index b7536b2..8dd956b 100644 --- a/src/contentpluginfactory.h +++ b/src/contentpluginfactory.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/fontadapter.cpp b/src/fontadapter.cpp index 658ffbd..6f2b52f 100644 --- a/src/fontadapter.cpp +++ b/src/fontadapter.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/fontadapter.h b/src/fontadapter.h index 08ee332..150ad15 100644 --- a/src/fontadapter.h +++ b/src/fontadapter.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/imageadapter.cpp b/src/imageadapter.cpp index c33a593..fa90d41 100644 --- a/src/imageadapter.cpp +++ b/src/imageadapter.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/imageadapter.h b/src/imageadapter.h index 6837a6e..8dbe8ee 100644 --- a/src/imageadapter.h +++ b/src/imageadapter.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/ipc/ipcclient.cpp b/src/ipc/ipcclient.cpp index ada2511..a256bc3 100644 --- a/src/ipc/ipcclient.cpp +++ b/src/ipc/ipcclient.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -50,7 +51,7 @@ public: /*! * \class IpcClient - * \brief Client to send remote calls to an IpcServer + * \brief Client to send remote calls to an IpcServer. * \inmodule ipc * * The IPC system uses the normalized signal/slot signature to @@ -381,34 +382,33 @@ qint64 IpcClient::sendPackage(const QString &method, const QByteArray &data) } /*! - * \fn void IpcClient::connected(); - * Emitted once when the connection to the server is established + * \fn IpcClient::connected() + * Emitted once when the connection to the server is established. */ /*! - * \fn void IpcClient::disconnected(); - * Emitted once when the connection to the server is terminated + * \fn IpcClient::disconnected() + * Emitted once when the connection to the server is terminated. */ /*! - * \fn void IpcClient::connectionError(QAbstractSocket::SocketError socketError); + * \fn IpcClient::connectionError(QAbstractSocket::SocketError socketError) * Emitted when an error happens when connecting or disconnecting from the server - * \a socketError describes what error happened + * \a socketError describes what error happened. */ /*! - * \fn void IpcClient::sentSuccessfully(const QUuid& uuid); + * \fn IpcClient::sentSuccessfully(const QUuid& uuid) * Emitted when the Package identified by \a uuid was successfully sent. */ /*! - * \fn void IpcClient::sendingError(const QUuid& uuid, QAbstractSocket::SocketError socketError); - * Emitted when an error happens when sending the Package identified by \a uuid. - * \a socketError describes what error happened + * \fn IpcClient::sendingError(const QUuid& uuid, QAbstractSocket::SocketError socketError) + * Emitted when an error \a socketError occurred while sending a Package identified by \a uuid. */ /*! - * \fn void IpcClient::received(const QString& method, const QByteArray& content) + * \fn IpcClient::received(const QString& method, const QByteArray& content) * - * Called when a RPC call was received. Provides the \a method and \a content + * Called when an RPC call was received. Provides the \a method and the \a content. */ diff --git a/src/ipc/ipcclient.h b/src/ipc/ipcclient.h index 7e6aedb..0a19f27 100644 --- a/src/ipc/ipcclient.h +++ b/src/ipc/ipcclient.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/ipc/ipcconnection.cpp b/src/ipc/ipcconnection.cpp index 32c038e..28d4919 100644 --- a/src/ipc/ipcconnection.cpp +++ b/src/ipc/ipcconnection.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/ipc/ipcconnection.h b/src/ipc/ipcconnection.h index de95296..2d2092f 100644 --- a/src/ipc/ipcconnection.h +++ b/src/ipc/ipcconnection.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/ipc/ipcserver.cpp b/src/ipc/ipcserver.cpp index 3d8288c..d303787 100644 --- a/src/ipc/ipcserver.cpp +++ b/src/ipc/ipcserver.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/ipc/ipcserver.h b/src/ipc/ipcserver.h index e61d037..c0b0ea1 100644 --- a/src/ipc/ipcserver.h +++ b/src/ipc/ipcserver.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/livedocument.cpp b/src/livedocument.cpp index d4347cf..3429636 100644 --- a/src/livedocument.cpp +++ b/src/livedocument.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -35,7 +36,7 @@ /*! * \class LiveDocument - * \brief Encapsulates a relative path to a workspace document + * \brief Encapsulates a relative path to a workspace document. * \inmodule qmllive */ diff --git a/src/livedocument.h b/src/livedocument.h index 6aa9b0c..4d538e1 100644 --- a/src/livedocument.h +++ b/src/livedocument.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/livehubengine.cpp b/src/livehubengine.cpp index 39208bf..b3bd56f 100644 --- a/src/livehubengine.cpp +++ b/src/livehubengine.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -40,7 +41,7 @@ /*! * \class LiveHubEngine - * \brief The LiveHubEngine class watches over a workspace and notifies a node on changes + * \brief The LiveHubEngine class watches over a workspace and notifies a node on changes. * \inmodule qmllive * * The live hub watches over a workspace and notifies a live node about changed files. A @@ -48,6 +49,18 @@ */ /*! + \enum LiveHubEngine::Error + \brief Describes error state of an engine + + \value NoError + No error + \value WatcherMaximumReached + The maximum number of watches set with setMaximumWatches() was exceeded + \value WatcherSystemError + Watching a directory for changes failed for an unspecified reason + */ + +/*! * Standard constructor using \a parent as parent */ LiveHubEngine::LiveHubEngine(QObject *parent) @@ -56,6 +69,7 @@ LiveHubEngine::LiveHubEngine(QObject *parent) , m_filePublishingActive(false) { connect(m_watcher, &Watcher::directoriesChanged, this, &LiveHubEngine::directoriesChanged); + connect(m_watcher, &Watcher::errorChanged, this, &LiveHubEngine::watcherErrorChanged); } /*! @@ -95,6 +109,38 @@ LiveDocument LiveHubEngine::activePath() const } /*! + * Returns true if error() is not NoError + */ +bool LiveHubEngine::hasError() +{ + return m_error != NoError; +} + +/*! + * Returns current Error + */ +LiveHubEngine::Error LiveHubEngine::error() +{ + return m_error; +} + +/*! + * Returns the maximum number of watched directories + */ +int LiveHubEngine::maximumWatches() +{ + return Watcher::maximumWatches(); +} + +/*! + * Sets the maximum number of watched directories to \a maximumWatches + */ +void LiveHubEngine::setMaximumWatches(int maximumWatches) +{ + Watcher::setMaximumWatches(maximumWatches); +} + +/*! * Handles watcher changes signals. */ void LiveHubEngine::directoriesChanged(const QStringList &changes) @@ -110,6 +156,31 @@ void LiveHubEngine::directoriesChanged(const QStringList &changes) } /*! + * Handles watcher error signals + */ +void LiveHubEngine::watcherErrorChanged() +{ + Error newError = NoError; + switch (m_watcher->error()) { + case Watcher::NoError: + newError = NoError; + break; + case Watcher::MaximumReached: + newError = WatcherMaximumReached; + break; + case Watcher::SystemError: + newError = WatcherSystemError; + break; + } + + if (newError == m_error) + return; + + m_error = newError; + emit errorChanged(); +} + +/*! * Publish the whole workspace to a connected node. */ void LiveHubEngine::publishWorkspace() @@ -186,3 +257,7 @@ void LiveHubEngine::setFilePublishingActive(bool on) * The signal is emitted when the workspace identified by \a workspace has changed */ +/*! + * \fn void LiveHubEngine::errorChanged() + * The signal is emitted when the error state desctibed by error() changed + */ diff --git a/src/livehubengine.h b/src/livehubengine.h index 266e07e..160ae53 100644 --- a/src/livehubengine.h +++ b/src/livehubengine.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -43,11 +44,23 @@ class QMLLIVESHARED_EXPORT LiveHubEngine : public QObject { Q_OBJECT public: + enum Error { + NoError, + WatcherMaximumReached, + WatcherSystemError, + }; + explicit LiveHubEngine(QObject *parent = 0); void setWorkspace(const QString& path); QString workspace() const; LiveDocument activePath() const; + + bool hasError(); + Error error(); + + static int maximumWatches(); + static void setMaximumWatches(int maximumWatches); public Q_SLOTS: void setActivePath(const LiveDocument& path); void setFilePublishingActive(bool on); @@ -59,13 +72,16 @@ Q_SIGNALS: void fileChanged(const LiveDocument& document); void activateDocument(const LiveDocument& document); void workspaceChanged(const QString& workspace); + void errorChanged(); private Q_SLOTS: void directoriesChanged(const QStringList& changes); + void watcherErrorChanged(); private: void publishDirectory(const QString& dirPath, bool fileChange); private: Watcher *m_watcher; bool m_filePublishingActive; LiveDocument m_activePath; + Error m_error = NoError; }; diff --git a/src/livenodeengine.cpp b/src/livenodeengine.cpp index 5feb843..9e9258b 100644 --- a/src/livenodeengine.cpp +++ b/src/livenodeengine.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/livenodeengine.h b/src/livenodeengine.h index 78eebfe..60ae574 100644 --- a/src/livenodeengine.h +++ b/src/livenodeengine.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/livert/error_qt5.qml b/src/livert/error_qt5.qml index 94e9ef1..c2ead27 100644 --- a/src/livert/error_qt5.qml +++ b/src/livert/error_qt5.qml @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/livert/error_qt5_controls.qml b/src/livert/error_qt5_controls.qml index 9d39710..ffd0caf 100644 --- a/src/livert/error_qt5_controls.qml +++ b/src/livert/error_qt5_controls.qml @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/livert/folderview_qt5.qml b/src/livert/folderview_qt5.qml index 3b09704..7c98a02 100644 --- a/src/livert/folderview_qt5.qml +++ b/src/livert/folderview_qt5.qml @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/livert/folderview_qt5_controls.qml b/src/livert/folderview_qt5_controls.qml index d2a6793..3d359e6 100644 --- a/src/livert/folderview_qt5_controls.qml +++ b/src/livert/folderview_qt5_controls.qml @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/livert/fontviewer_qt5.qml b/src/livert/fontviewer_qt5.qml index b74014a..fb7ecd6 100644 --- a/src/livert/fontviewer_qt5.qml +++ b/src/livert/fontviewer_qt5.qml @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/livert/fontviewer_qt5_controls.qml b/src/livert/fontviewer_qt5_controls.qml index d958b5d..5ffadd0 100644 --- a/src/livert/fontviewer_qt5_controls.qml +++ b/src/livert/fontviewer_qt5_controls.qml @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/livert/imageviewer_qt5.qml b/src/livert/imageviewer_qt5.qml index 9728d72..d31410d 100644 --- a/src/livert/imageviewer_qt5.qml +++ b/src/livert/imageviewer_qt5.qml @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/livert/imageviewer_qt5_controls.qml b/src/livert/imageviewer_qt5_controls.qml index 9728d72..d31410d 100644 --- a/src/livert/imageviewer_qt5_controls.qml +++ b/src/livert/imageviewer_qt5_controls.qml @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/liveruntime.cpp b/src/liveruntime.cpp index 22c8327..48969d0 100644 --- a/src/liveruntime.cpp +++ b/src/liveruntime.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/liveruntime.h b/src/liveruntime.h index 7be16ab..a95622f 100644 --- a/src/liveruntime.h +++ b/src/liveruntime.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/logger.cpp b/src/logger.cpp index 865b35a..90a0dca 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -38,7 +39,7 @@ QMutex Logger::m_mutex; /*! * \class Logger - * \brief Installs a qt messageHandler and receives all log messages + * \brief Installs a qt messageHandler and receives all log messages. * \inmodule qmllive * * The intention is to use this class if you want to display the log into widget diff --git a/src/logger.h b/src/logger.h index a5e0b49..774c2e1 100644 --- a/src/logger.h +++ b/src/logger.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/logreceiver.cpp b/src/logreceiver.cpp index 7cec063..7b91b1a 100644 --- a/src/logreceiver.cpp +++ b/src/logreceiver.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -36,7 +37,7 @@ /*! * \class LogReceiver - * \brief Connects to a port and waits for log messages sent via udp + * \brief Connects to a port and waits for log messages sent via UDP. * \inmodule qmllive * * \sa Logger, RemoteLogger diff --git a/src/logreceiver.h b/src/logreceiver.h index bd4ddfb..86e993e 100644 --- a/src/logreceiver.h +++ b/src/logreceiver.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/previewGenerator/main.cpp b/src/previewGenerator/main.cpp index a17e66d..5c609fc 100644 --- a/src/previewGenerator/main.cpp +++ b/src/previewGenerator/main.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -45,6 +46,8 @@ #include <QDebug> #include <QTextStream> +#include "../qmllive_version.h" + void handlePreview(QLocalSocket *socket); class PreviewServer : public QObject @@ -59,8 +62,25 @@ public: bool listen() { - QLocalServer::removeServer("QmlLivePreviewGenerator"); - return m_server->listen("QmlLivePreviewGenerator"); + Q_ASSERT(!qApp->applicationName().isEmpty()); + Q_ASSERT(!qApp->organizationDomain().isEmpty() || !qApp->organizationName().isEmpty()); + + QString userName; +#if defined(Q_OS_UNIX) + userName = qgetenv("USER"); +#elif defined(Q_OS_WIN) + userName = qgetenv("USERNAME"); +#endif + if (userName.isEmpty()) + qWarning("Failed to determine system user name"); + + QString serverName = QString::fromLatin1("%1.%2-%3") + .arg(qApp->organizationDomain().isEmpty() ? qApp->organizationName() : qApp->organizationDomain()) + .arg(qApp->applicationName()) + .arg(userName); + + QLocalServer::removeServer(serverName); + return m_server->listen(serverName); } QString serverName() const @@ -93,6 +113,10 @@ Q_LOGGING_CATEGORY(pg, "PreviewGenerator", QtInfoMsg) int main (int argc, char** argv) { + QGuiApplication::setApplicationName("QmlLivePreviewGenerator"); + QGuiApplication::setOrganizationDomain(QLatin1String(QMLLIVE_ORGANIZATION_DOMAIN)); + QGuiApplication::setOrganizationName(QLatin1String(QMLLIVE_ORGANIZATION_NAME)); + QGuiApplication app(argc, argv); app.setQuitOnLastWindowClosed(false); diff --git a/src/projectmanager.cpp b/src/projectmanager.cpp new file mode 100644 index 0000000..531f06e --- /dev/null +++ b/src/projectmanager.cpp @@ -0,0 +1,164 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QmlLive tool. +** +** $QT_BEGIN_LICENSE:GPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite licenses may use +** this file in accordance with the commercial license agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and The Qt Company. For +** licensing terms and conditions see https://www.qt.io/terms-conditions. +** For further information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: GPL-3.0 +** +****************************************************************************/ + +#include "projectmanager.h" + +#include <QFile> +#include <QDebug> +#include <QJsonDocument> +#include <QJsonObject> +#include <QJsonArray> + +const QLatin1String MainKey("main"); +const QLatin1String WorkspaceKey("workspace"); +const QLatin1String ImportsKey("imports"); +const QLatin1String QmlLiveExtension(".qmllive"); + +ProjectManager::ProjectManager(QObject *parent) + : QObject(parent) + , m_mainDocument("main.qml") + , m_workspace("") + , m_projectName("") + , m_projectLocation("") +{ + +} + +bool ProjectManager::read(const QString &path) +{ + reset(); + + QFile file(path); + if (!file.open(QIODevice::ReadOnly)) { + qWarning() << "Unable to open document " << path; + return false; + } + m_projectLocation = QFileInfo(path).absolutePath(); + m_projectName = file.fileName(); + QByteArray data = file.readAll(); + QJsonParseError error; + QJsonDocument document = QJsonDocument::fromJson(data, &error); + if (error.error) { + qWarning() << "error parsing JSON document" << error.errorString(); + return false; + } + if (!document.isObject()) { + qWarning() << "Document must be a JSON object"; + return false; + } + QJsonObject root = document.object(); + if (root.contains(MainKey)) + m_mainDocument = root.value(MainKey).toString(); + if (root.contains(WorkspaceKey)) + { + m_workspace = root.value(WorkspaceKey).toString(); + } + if (root.contains(ImportsKey) && root.value(ImportsKey).isArray()) { + QJsonArray imports = root.value(ImportsKey).toArray(); + for (QJsonValue value : imports) + m_imports.append(value.toString()); + } + return true; +} + +void ProjectManager::write(const QString &path) +{ + qInfo()<<"Writing into " << path; + QFile file(path); + if (!file.open(QIODevice::WriteOnly)) { + qWarning() << "Unable to write to document: " << path; + return; + } + m_projectLocation = QFileInfo(path).absolutePath(); + QJsonObject root; + root.insert(MainKey, QJsonValue(m_mainDocument)); + root.insert(WorkspaceKey, QJsonValue(m_workspace)); + QJsonArray imports; + for (const QString &import : m_imports) + imports.append(QJsonValue(import)); + root.insert(ImportsKey, imports); + QJsonDocument document(root); + file.write(document.toJson()); +} + +void ProjectManager::create(const QString &projectName) +{ + m_projectName = projectName; + QString path = QString(projectName).append(QmlLiveExtension); + qInfo()<<"CREATING Project------ "<<path; + write(path); +} + +QString ProjectManager::mainDocument() const +{ + return m_mainDocument; +} + +QString ProjectManager::workspace() const +{ + return m_workspace; +} + +QStringList ProjectManager::imports() const +{ + return m_imports; +} + +QString ProjectManager::projectLocation() const +{ + return m_projectLocation; +} + +void ProjectManager::reset() +{ + m_mainDocument = QString("main.qml"); + m_workspace = QString(""); + m_imports.clear(); +} + +void ProjectManager::setProjectName(const QString &projectName) +{ + m_projectName = projectName; +} +void ProjectManager::setMainDocument(const QString &mainDocument) +{ + m_mainDocument = mainDocument; +} +void ProjectManager::setWorkspace(const QString &workspace) +{ + m_workspace = workspace; +} +void ProjectManager::setImports(const QStringList &imports) +{ + m_imports = imports; +} + diff --git a/src/projectmanager.h b/src/projectmanager.h new file mode 100644 index 0000000..3289aed --- /dev/null +++ b/src/projectmanager.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QmlLive tool. +** +** $QT_BEGIN_LICENSE:GPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite licenses may use +** this file in accordance with the commercial license agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and The Qt Company. For +** licensing terms and conditions see https://www.qt.io/terms-conditions. +** For further information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: GPL-3.0 +** +****************************************************************************/ + +#pragma once + +#include <QtCore> + +#include "qmllive_global.h" + +class QMLLIVESHARED_EXPORT ProjectManager : public QObject +{ + Q_OBJECT +public: + explicit ProjectManager(QObject *parent = nullptr); + + bool read(const QString &path); + void write(const QString &path=QString()); + void create(const QString &projectName); + QString mainDocument() const; + QString workspace() const; + QStringList imports() const; + QString projectLocation() const; + + void setProjectName(const QString &projectName); + void setMainDocument(const QString &mainDocument); + void setWorkspace(const QString &workspace); + void setImports(const QStringList &imports); +private: + void reset(); + +private: + QString m_mainDocument; + QString m_workspace; + QStringList m_imports; + QString m_projectName; + QString m_projectLocation; +}; diff --git a/src/qmlhelper.cpp b/src/qmlhelper.cpp index 72dc1af..1de9716 100644 --- a/src/qmlhelper.cpp +++ b/src/qmlhelper.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -34,12 +35,12 @@ /*! * \class QmlHelper - * \brief Provides a set of helper functions to setup your QML viewer + * \brief Provides a set of helper functions to setup your QML viewer. * \inmodule qmllive */ /*! - * Standard constructor using \a parent as parent + * Standard constructor using \a parent as parent. */ QmlHelper::QmlHelper(QObject *parent) : QObject(parent) @@ -47,9 +48,10 @@ QmlHelper::QmlHelper(QObject *parent) : } /*! - * Loads dummy data from a "dummydata" folder in the workspace folder - * \a engine defines the Engine where you want to export the dummy data to - * The "dummydata" will be searched in the "dummydata" sub directory of \a workspace + * Loads dummy data from a "dummydata" folder in the workspace folder. + * \a engine defines the Engine where you want to export the dummy data to. + * The "dummydata" will be searched in the "dummydata" subdirectory of \a + * workspace. */ void QmlHelper::loadDummyData(QQmlEngine *engine, const QString &workspace) { diff --git a/src/qmlhelper.h b/src/qmlhelper.h index 38e2552..07a8ec2 100644 --- a/src/qmlhelper.h +++ b/src/qmlhelper.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/qmllive.cpp b/src/qmllive.cpp index 6318cf5..8b4c5ce 100644 --- a/src/qmllive.cpp +++ b/src/qmllive.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/qmllive.h b/src/qmllive.h index a1503b0..5948da1 100644 --- a/src/qmllive.h +++ b/src/qmllive.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/qmllive_global.h b/src/qmllive_global.h index cba8d4b..d2bb0f6 100755 --- a/src/qmllive_global.h +++ b/src/qmllive_global.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/qmllive_version.h b/src/qmllive_version.h index 5b5be59..f3ecd81 100644 --- a/src/qmllive_version.h +++ b/src/qmllive_version.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -33,7 +34,7 @@ #include <QtGlobal> -const char *const QMLLIVE_COPYRIGHT_NOTICE = "Copyright 2016 Pelagicore AG. All rights reserved."; +const char *const QMLLIVE_COPYRIGHT_NOTICE = "Copyright (C) 2019 Luxoft Sweden AB. All rights reserved."; const char *const QMLLIVE_VERSION_STR = QT_STRINGIFY(QMLLIVE_VERSION); @@ -53,6 +54,6 @@ const char *const QMLLIVE_REVISION_STR = ""; const char *const QMLLIVE_ORGANIZATION_NAME = QT_STRINGIFY(QMLLIVE_SETTINGS_VARIANT); const char *const QMLLIVE_ORGANIZATION_DOMAIN = ""; #else -const char *const QMLLIVE_ORGANIZATION_NAME = "Pelagicore"; -const char *const QMLLIVE_ORGANIZATION_DOMAIN = "pelagicore.com"; +const char *const QMLLIVE_ORGANIZATION_NAME = "Luxoft Sweden AB"; +const char *const QMLLIVE_ORGANIZATION_DOMAIN = "luxoft.com"; #endif diff --git a/src/remotelogger.cpp b/src/remotelogger.cpp index 57a9ace..31ea3b8 100644 --- a/src/remotelogger.cpp +++ b/src/remotelogger.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -34,7 +35,7 @@ /*! * \class RemoteLogger - * \brief Installs a qt messageHandler and sends the logs over udp + * \brief Installs a Qt messageHandler and sends the logs over UDP. * \inmodule qmllive * * \sa Logger, LogReceiver @@ -52,7 +53,7 @@ RemoteLogger::RemoteLogger(QObject *parent) : } /*! - * Sets the \a address where the log messages will be sent to + * Sets the \a address where the log messages will be sent to. * \sa setPort() */ void RemoteLogger::setHostAddress(const QHostAddress &address) @@ -61,7 +62,7 @@ void RemoteLogger::setHostAddress(const QHostAddress &address) } /*! - * Sets the \a port where the log messages will be sent to + * Sets the \a port where the log messages will be sent to. * \sa setHostAddress() */ void RemoteLogger::setPort(int port) @@ -87,7 +88,7 @@ void RemoteLogger::broadcast(int type, const QString &msg, const QUrl &url, int } /*! - * Broadcasts each error from the \a errors + * Broadcasts each error from the \a errors. */ void RemoteLogger::appendToLog(const QList<QQmlError> &errors) { diff --git a/src/remotelogger.h b/src/remotelogger.h index 6b4f947..234874b 100644 --- a/src/remotelogger.h +++ b/src/remotelogger.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/remotepublisher.cpp b/src/remotepublisher.cpp index ca24924..5984dae 100644 --- a/src/remotepublisher.cpp +++ b/src/remotepublisher.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -42,7 +43,7 @@ /*! * \class RemotePublisher - * \brief Publishes hub changes to a remote node + * \brief Publishes hub changes to a remote node. * \inmodule qmllive * * To see the progress which commands were really sent successfully to to the server diff --git a/src/remotepublisher.h b/src/remotepublisher.h index 13840f4..5c1f930 100644 --- a/src/remotepublisher.h +++ b/src/remotepublisher.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/remotereceiver.cpp b/src/remotereceiver.cpp index 0175d44..0cd707e 100644 --- a/src/remotereceiver.cpp +++ b/src/remotereceiver.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -45,7 +46,7 @@ /*! * \class RemoteReceiver - * \brief Receives commands form the remote publisher + * \brief Receives commands from the remote publisher. * \inmodule qmllive * * Receives commands from a remote publisher to publish workspace files and to @@ -117,8 +118,10 @@ bool RemoteReceiver::listen(int port, ConnectionOptions options) loop.quit(); }); loop.exec(); - if (!pinOk) + if (!pinOk) { + qWarning() << "Refused connection from QmlLive Bench: Wrong pin"; return false; + } } if (m_connectionOptions & UpdateDocumentsOnConnect) { @@ -128,9 +131,13 @@ bool RemoteReceiver::listen(int port, ConnectionOptions options) loop.quit(); }); loop.exec(); - if (!finishedOk) + if (!finishedOk) { + qWarning() << "Initial workspace synchronization with QmlLive Bench failed"; return false; + } } + + qInfo() << "QmlLive Bench connected"; } return true; @@ -179,6 +186,7 @@ void RemoteReceiver::handleCall(const QString &method, const QByteArray &content } else if (m_client) { emit pinOk(false); m_client->send("pinOK(bool)", QByteArray::number(0)); + return; } } diff --git a/src/remotereceiver.h b/src/remotereceiver.h index 4309a30..740f8f5 100644 --- a/src/remotereceiver.h +++ b/src/remotereceiver.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/runtime/main.cpp b/src/runtime/main.cpp index 3058e24..d4a7cf3 100644 --- a/src/runtime/main.cpp +++ b/src/runtime/main.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/runtime/qmlsplash/splash-qt4.qml b/src/runtime/qmlsplash/splash-qt4.qml index d6c2654..19943d7 100644 --- a/src/runtime/qmlsplash/splash-qt4.qml +++ b/src/runtime/qmlsplash/splash-qt4.qml @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/runtime/qmlsplash/splash-qt5.qml b/src/runtime/qmlsplash/splash-qt5.qml index 72048e5..4f024fb 100644 --- a/src/runtime/qmlsplash/splash-qt5.qml +++ b/src/runtime/qmlsplash/splash-qt5.qml @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/src.pri b/src/src.pri index 1af18e4..38504b4 100644 --- a/src/src.pri +++ b/src/src.pri @@ -20,7 +20,8 @@ SOURCES += \ $$PWD/logger.cpp \ $$PWD/remotelogger.cpp \ $$PWD/logreceiver.cpp \ - $$PWD/fontadapter.cpp + $$PWD/fontadapter.cpp \ + $$PWD/projectmanager.cpp public_headers += \ $$PWD/livedocument.h \ @@ -33,7 +34,8 @@ public_headers += \ $$PWD/remotepublisher.h \ $$PWD/remotereceiver.h \ $$PWD/contentadapterinterface.h \ - $$PWD/remotelogger.h + $$PWD/remotelogger.h \ + $$PWD/projectmanager.h HEADERS += \ $$public_headers \ diff --git a/src/src.pro b/src/src.pro index b18eb1c..625733e 100644 --- a/src/src.pro +++ b/src/src.pro @@ -1,4 +1,5 @@ include(../qmllive.pri) +include(../doc/doc.pri) TEMPLATE = subdirs CONFIG += ordered diff --git a/src/watcher.cpp b/src/watcher.cpp index 2be3abb..e1c4556 100644 --- a/src/watcher.cpp +++ b/src/watcher.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -41,6 +42,20 @@ */ /*! + \enum Watcher::Error + \brief Describes error state of a Watcher + + \value NoError + No error + \value MaximumReached + The maximum number of watches set with setMaximumWatches() was exceeded + \value SystemError + QFileSystemWatcher::addPath failed for an unspecified reason + */ + +int Watcher::s_maximumWatches = -1; + +/*! Default Constructor using parent as parent */ Watcher::Watcher(QObject *parent) @@ -63,12 +78,8 @@ Watcher::Watcher(QObject *parent) void Watcher::setDirectory(const QString &path) { m_rootDir = QDir(path); - if (!m_watcher->directories().isEmpty()) { - m_watcher->removePaths(m_watcher->directories()); - } - if (!m_watcher->files().isEmpty()) { - m_watcher->removePaths(m_watcher->files()); - } + removeAllPaths(); + setError(NoError); addDirectoriesRecursively(m_rootDir.absolutePath()); } @@ -81,28 +92,90 @@ QString Watcher::directory() const } /*! + \fn Watcher::maximumWatches() + + Returns the maximum number of watched directories + */ + +/*! + Sets the maximum number of watched directories + + This will only take effect with next setDirectory() call. + */ +void Watcher::setMaximumWatches(int maximumWatches) +{ + s_maximumWatches = maximumWatches; +} + +/*! + \fn Watcher::hasError() const + + Returns true if error() is not NoError + */ + +/*! + \fn Watcher::error() const + + Describes the current error state of this watcher + */ + +/*! + \fn Watcher::errorChanged() + + Notifies about error() change + */ + +/*! Add path and all it's SubDirectory to the internal used QFileSystemWatcher */ void Watcher::addDirectoriesRecursively(const QString &path) { // qDebug() << "scan: " << path; - if (!m_watcher->directories().contains(path)) { - m_watcher->addPath(path); - } + addDirectory(path); QDirIterator iter(path, QDir::Dirs|QDir::NoDotAndDotDot, QDirIterator::Subdirectories); - while (iter.hasNext()) { + while (iter.hasNext() && !hasError()) { QDir entry(iter.next()); - if (!m_watcher->directories().contains(entry.absolutePath())) { - m_watcher->addPath(entry.absolutePath()); + addDirectory(entry.absolutePath()); + } +} - //If we couldn't add it we reached the filesystem limit - if (!m_watcher->directories().contains(entry.absolutePath())) { - qWarning() << "Watcher limit reached. Please reduce the number of files you are watching !!!"; - return; - } - } +void Watcher::addDirectory(const QString &path) +{ + if (m_watcher->directories().contains(path)) + return; + + if (s_maximumWatches > 0 && + m_watcher->directories().count() + m_watcher->files().count() > s_maximumWatches) { + removeAllPaths(); + setError(MaximumReached); + return; } + m_watcher->addPath(path); + + if (!m_watcher->directories().contains(path)) { + removeAllPaths(); + setError(SystemError); + } +} + +void Watcher::removeAllPaths() +{ + if (!m_watcher->directories().isEmpty()) { + m_watcher->removePaths(m_watcher->directories()); + } + if (!m_watcher->files().isEmpty()) { + m_watcher->removePaths(m_watcher->files()); + } +} + +void Watcher::setError(Watcher::Error error) +{ + if (m_error == error) + return; + + m_error = error; + emit errorChanged(); } void Watcher::recordChange(const QString &path) diff --git a/src/watcher.h b/src/watcher.h index a17e28a..7db5408 100644 --- a/src/watcher.h +++ b/src/watcher.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -37,20 +38,35 @@ class Watcher : public QObject { Q_OBJECT public: + enum Error { + NoError, + MaximumReached, + SystemError, + }; + explicit Watcher(QObject *parent = 0); void setDirectory(const QString& path); QString directory() const; + bool hasError() const { return m_error != NoError; } + Error error() const { return m_error; } + static int maximumWatches() { return s_maximumWatches; } + static void setMaximumWatches(int maximumWatches); private Q_SLOTS: void recordChange(const QString &path); void notifyChanges(); Q_SIGNALS: void directoriesChanged(const QStringList& changes); - + void errorChanged(); private: void addDirectoriesRecursively(const QString& path); + void addDirectory(const QString &path); + void removeAllPaths(); + void setError(Error error); + static int s_maximumWatches; QFileSystemWatcher *m_watcher; QDir m_rootDir; QTimer *m_waitTimer; QStringList m_changes; + Error m_error = NoError; }; diff --git a/src/widgets/filesystemmodel.cpp b/src/widgets/filesystemmodel.cpp index f3622b9..a66d594 100644 --- a/src/widgets/filesystemmodel.cpp +++ b/src/widgets/filesystemmodel.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/widgets/filesystemmodel.h b/src/widgets/filesystemmodel.h index 27b511e..758fed6 100644 --- a/src/widgets/filesystemmodel.h +++ b/src/widgets/filesystemmodel.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/widgets/logview.cpp b/src/widgets/logview.cpp index f291faf..3a6e1a5 100644 --- a/src/widgets/logview.cpp +++ b/src/widgets/logview.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -38,7 +39,7 @@ LogView::LogView(bool createLogger, QWidget *parent) { m_log->setReadOnly(true); m_log->setMaximumBlockCount(1000); - m_log->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse); + m_log->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse | Qt::TextSelectableByKeyboard); QVBoxLayout *layout = new QVBoxLayout(this); layout->setMargin(0); diff --git a/src/widgets/logview.h b/src/widgets/logview.h index 7d1874a..1be6b69 100644 --- a/src/widgets/logview.h +++ b/src/widgets/logview.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/widgets/windowwidget.cpp b/src/widgets/windowwidget.cpp index 2cfd3c3..1d6f234 100644 --- a/src/widgets/windowwidget.cpp +++ b/src/widgets/windowwidget.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/widgets/windowwidget.h b/src/widgets/windowwidget.h index 789b8e2..bff9072 100644 --- a/src/widgets/windowwidget.h +++ b/src/widgets/windowwidget.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/widgets/workspacedelegate.cpp b/src/widgets/workspacedelegate.cpp index 8f61cee..9b967e9 100644 --- a/src/widgets/workspacedelegate.cpp +++ b/src/widgets/workspacedelegate.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/widgets/workspacedelegate.h b/src/widgets/workspacedelegate.h index 2d0451a..2427d82 100644 --- a/src/widgets/workspacedelegate.h +++ b/src/widgets/workspacedelegate.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/src/widgets/workspaceview.cpp b/src/widgets/workspaceview.cpp index a1f26f8..08eb9b4 100644 --- a/src/widgets/workspaceview.cpp +++ b/src/widgets/workspaceview.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -73,7 +74,7 @@ WorkspaceView::WorkspaceView(QWidget *parent) // setup layout QVBoxLayout *layout = new QVBoxLayout(this); layout->addWidget(m_view); - layout->setMargin(1); + layout->setContentsMargins(0, 0, 0, 0); setLayout(layout); m_view->setDragEnabled(true); @@ -168,3 +169,22 @@ void WorkspaceView::selectIndex(const QModelIndex &index) indexActivated(index); //m_view->selectionModel()->select(index, QItemSelectionModel::ClearAndSelect); } + +void WorkspaceView::restoreFromSettings(QSettings *s) +{ + hideNonQMLFiles(s->value("only_qml_files/enabled").toBool()); +} + +void WorkspaceView::hideNonQMLFiles(bool hide) +{ + QStringList filters; + if (hide) { + filters << "*.qml"; + } + else { + filters << "*.*"; + } + m_model->setNameFilters(filters); + m_model->setNameFilterDisables(false); + m_view->setModel(m_model); +} diff --git a/src/widgets/workspaceview.h b/src/widgets/workspaceview.h index dab0df6..aa0ef1d 100644 --- a/src/widgets/workspaceview.h +++ b/src/widgets/workspaceview.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. @@ -48,12 +49,14 @@ public: QString rootPath() const; void setDirectoriesSelectable(bool enabled); bool directoriesSelectable() const; + void restoreFromSettings(QSettings *s); public Q_SLOTS: void setRootPath(const QString& dirPath); void activateDocument(const LiveDocument& path); void activateRootPath(); void goUp(); + void hideNonQMLFiles(bool hide); Q_SIGNALS: void pathActivated(const LiveDocument& path); diff --git a/testData/qml/explicit-size.qml b/testData/qml/explicit-size.qml index c52533e..222c703 100644 --- a/testData/qml/explicit-size.qml +++ b/testData/qml/explicit-size.qml @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/testData/qml/no-explicit-size.qml b/testData/qml/no-explicit-size.qml index 1ba6cbc..0c49e53 100644 --- a/testData/qml/no-explicit-size.qml +++ b/testData/qml/no-explicit-size.qml @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/testData/qml/two-windows.qml b/testData/qml/two-windows.qml index 59d56c8..9c26ed0 100644 --- a/testData/qml/two-windows.qml +++ b/testData/qml/two-windows.qml @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/tests/manual_tests/javascript/lib.js b/tests/manual_tests/javascript/lib.js index c00908f..625d3ef 100644 --- a/tests/manual_tests/javascript/lib.js +++ b/tests/manual_tests/javascript/lib.js @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/tests/manual_tests/javascript/pragma_main.qml b/tests/manual_tests/javascript/pragma_main.qml index 8afd3ff..af1e256 100644 --- a/tests/manual_tests/javascript/pragma_main.qml +++ b/tests/manual_tests/javascript/pragma_main.qml @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/tests/manual_tests/javascript/pragmalib.js b/tests/manual_tests/javascript/pragmalib.js index ce65caf..2d97435 100644 --- a/tests/manual_tests/javascript/pragmalib.js +++ b/tests/manual_tests/javascript/pragmalib.js @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/tests/testipc/tst_testipc.cpp b/tests/testipc/tst_testipc.cpp index 197b4d2..843d46e 100644 --- a/tests/testipc/tst_testipc.cpp +++ b/tests/testipc/tst_testipc.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. diff --git a/tests/tests.pro b/tests/tests.pro index 3179cdf..332d12f 100644 --- a/tests/tests.pro +++ b/tests/tests.pro @@ -1,3 +1,4 @@ +include(../doc/doc.pri) TEMPLATE = subdirs diff --git a/tests/testsync/tst_testsync.cpp b/tests/testsync/tst_testsync.cpp index 9382cac..115a2b8 100644 --- a/tests/testsync/tst_testsync.cpp +++ b/tests/testsync/tst_testsync.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 Pelagicore AG +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QmlLive tool. |