aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Kampas <martin.kampas@jolla.com>2016-11-05 08:49:59 +0100
committerJuergen Bocklage-Ryannel <juergen.bocklage-ryannel@pelagicore.com>2016-11-23 05:24:41 +0000
commit6b6c17f19bda671d6f9553662f1475241837f533 (patch)
tree056e7dce77f805474732b287e7d7aff81ff7bbf0
parentd99e8c0513cba836972be008007ea97ad145f236 (diff)
Consistently and reliably handle paths to workspace documents
Use relative paths. Consistently and reliably means Always. Change-Id: I660ad89a9b9b8baee782aa701ea101ea542c70ce Reviewed-by: Juergen Bocklage-Ryannel <juergen.bocklage-ryannel@pelagicore.com>
-rw-r--r--src/bench/allhostswidget.cpp3
-rw-r--r--src/bench/allhostswidget.h4
-rw-r--r--src/bench/benchlivenodeengine.cpp6
-rw-r--r--src/bench/host.cpp8
-rw-r--r--src/bench/host.h12
-rw-r--r--src/bench/hostmanager.cpp8
-rw-r--r--src/bench/hostmanager.h5
-rw-r--r--src/bench/hostmodel.cpp2
-rw-r--r--src/bench/hostwidget.cpp80
-rw-r--r--src/bench/hostwidget.h10
-rw-r--r--src/bench/main.cpp11
-rw-r--r--src/bench/mainwindow.cpp33
-rw-r--r--src/bench/mainwindow.h3
-rw-r--r--src/bench/options.cpp4
-rw-r--r--src/bench/options.h8
-rw-r--r--src/livedocument.cpp193
-rw-r--r--src/livedocument.h67
-rw-r--r--src/livehubengine.cpp21
-rw-r--r--src/livehubengine.h13
-rw-r--r--src/livenodeengine.cpp42
-rw-r--r--src/livenodeengine.h13
-rw-r--r--src/qmllive_global.h16
-rw-r--r--src/remotepublisher.cpp21
-rw-r--r--src/remotepublisher.h7
-rw-r--r--src/remotereceiver.cpp12
-rw-r--r--src/remotereceiver.h5
-rw-r--r--src/runtime/main.cpp3
-rw-r--r--src/src.pri2
-rw-r--r--src/watcher.cpp9
-rw-r--r--src/watcher.h1
-rw-r--r--src/widgets/workspaceview.cpp12
-rw-r--r--src/widgets/workspaceview.h10
32 files changed, 485 insertions, 159 deletions
diff --git a/src/bench/allhostswidget.cpp b/src/bench/allhostswidget.cpp
index add6e0e..899be34 100644
--- a/src/bench/allhostswidget.cpp
+++ b/src/bench/allhostswidget.cpp
@@ -31,6 +31,7 @@
#include "allhostswidget.h"
+#include "livedocument.h"
AllHostsWidget::AllHostsWidget(QWidget *parent) :
QWidget(parent)
@@ -95,6 +96,6 @@ void AllHostsWidget::dropEvent(QDropEvent *event)
QUrl url(event->mimeData()->text());
if (url.isLocalFile())
- emit currentFileChanged(url.toLocalFile());
+ emit currentFileChanged(LiveDocument::resolve(m_workspace, url.toLocalFile()));
event->acceptProposedAction();
}
diff --git a/src/bench/allhostswidget.h b/src/bench/allhostswidget.h
index 47f4460..a53785f 100644
--- a/src/bench/allhostswidget.h
+++ b/src/bench/allhostswidget.h
@@ -33,6 +33,8 @@
#include <QtWidgets>
+class LiveDocument;
+
class AllHostsWidget : public QWidget
{
Q_OBJECT
@@ -44,7 +46,7 @@ public:
signals:
void refreshAll();
void publishAll();
- void currentFileChanged(const QString file);
+ void currentFileChanged(const LiveDocument &file);
protected:
void dropEvent(QDropEvent *event);
diff --git a/src/bench/benchlivenodeengine.cpp b/src/bench/benchlivenodeengine.cpp
index abe1910..30dd5b5 100644
--- a/src/bench/benchlivenodeengine.cpp
+++ b/src/bench/benchlivenodeengine.cpp
@@ -108,7 +108,11 @@ void BenchLiveNodeEngine::initPlugins()
DirectoryPreviewAdapter *adapter = new DirectoryPreviewAdapter(this);
if (m_workspaceView) {
//This needs to be QueuedConnection because Qt5 doesn't like it to destruct it's object while it is in a signalHandler
- connect(adapter, SIGNAL(loadDocument(QString)), m_workspaceView, SLOT(activateDocument(QString)), Qt::QueuedConnection);
+ connect(adapter, &DirectoryPreviewAdapter::loadDocument,
+ this, [this](const QString &document) {
+ m_workspaceView->activateDocument(LiveDocument(document));
+ },
+ Qt::QueuedConnection);
}
QmlPreviewAdapter *previewAdapter = new QmlPreviewAdapter(this);
diff --git a/src/bench/host.cpp b/src/bench/host.cpp
index fb1f366..fc54513 100644
--- a/src/bench/host.cpp
+++ b/src/bench/host.cpp
@@ -73,7 +73,7 @@ QString Host::address() const
return m_address;
}
-QString Host::currentFile() const
+LiveDocument Host::currentFile() const
{
return m_currentFile;
}
@@ -109,7 +109,7 @@ void Host::setAddress(QString arg)
}
}
-void Host::setCurrentFile(QString arg)
+void Host::setCurrentFile(LiveDocument arg)
{
m_currentFile = arg;
emit currentFileChanged(arg);
@@ -208,7 +208,7 @@ void Host::saveToSettings(QSettings *s)
s->setValue("xOffset", xOffset());
s->setValue("yOffset", yOffset());
s->setValue("rotation", rotation());
- s->setValue("currentFile", currentFile());
+ s->setValue("currentFile", currentFile().relativeFilePath());
s->setValue("autoDiscoveryId", autoDiscoveryId().toString());
s->setValue("systemName", systemName());
s->setValue("productVersion", productVersion());
@@ -226,7 +226,7 @@ void Host::restoreFromSettings(QSettings *s)
setXOffset(s->value("xOffset").toInt());
setYOffset(s->value("yOffset").toInt());
setRotation(s->value("rotation").toInt());
- setCurrentFile(s->value("currentFile").toString());
+ setCurrentFile(LiveDocument(s->value("currentFile").toString()));
setAutoDiscoveryId(QUuid(s->value("autoDiscoveryId").toString()));
setSystemName(s->value("systemName").toString());
setProductVersion(s->value("productVersion").toString());
diff --git a/src/bench/host.h b/src/bench/host.h
index 658303c..e04b4a8 100644
--- a/src/bench/host.h
+++ b/src/bench/host.h
@@ -31,6 +31,8 @@
#pragma once
+#include "livedocument.h"
+
#include <QObject>
#include <QUuid>
#include <QMetaType>
@@ -51,7 +53,7 @@ public:
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(QString address READ address WRITE setAddress NOTIFY addressChanged)
Q_PROPERTY(int port READ port WRITE setPort NOTIFY portChanged)
- Q_PROPERTY(QString currentFile READ currentFile WRITE setCurrentFile NOTIFY currentFileChanged)
+ Q_PROPERTY(LiveDocument currentFile READ currentFile WRITE setCurrentFile NOTIFY currentFileChanged)
Q_PROPERTY(int xOffset READ xOffset WRITE setXOffset NOTIFY xOffsetChanged)
Q_PROPERTY(int yOffset READ yOffset WRITE setYOffset NOTIFY yOffsetChanged)
Q_PROPERTY(int rotation READ rotation WRITE setRotation NOTIFY rotationChanged)
@@ -67,7 +69,7 @@ public:
QString name() const;
QString address() const;
int port() const;
- QString currentFile() const;
+ LiveDocument currentFile() const;
int xOffset() const;
int yOffset() const;
int rotation() const;
@@ -88,7 +90,7 @@ signals:
void nameChanged(QString arg);
void addressChanged(QString arg);
void portChanged(int arg);
- void currentFileChanged(QString arg);
+ void currentFileChanged(LiveDocument arg);
void xOffsetChanged(int arg);
void yOffsetChanged(int arg);
void rotationChanged(int arg);
@@ -102,7 +104,7 @@ public slots:
void setName(QString arg);
void setAddress(QString arg);
void setPort(int arg);
- void setCurrentFile(QString arg);
+ void setCurrentFile(LiveDocument arg);
void setXOffset(int arg);
void setYOffset(int arg);
void setRotation(int arg);
@@ -117,7 +119,7 @@ private:
QString m_name;
QString m_address;
int m_port;
- QString m_currentFile;
+ LiveDocument m_currentFile;
int m_xOffset;
int m_yOffset;
int m_rotation;
diff --git a/src/bench/hostmanager.cpp b/src/bench/hostmanager.cpp
index cfce965..1d80eb4 100644
--- a/src/bench/hostmanager.cpp
+++ b/src/bench/hostmanager.cpp
@@ -82,9 +82,9 @@ void HostManager::setLiveHubEngine(LiveHubEngine *engine)
}
}
-void HostManager::followTreeSelection(const QString &currentFile)
+void HostManager::followTreeSelection(const LiveDocument &currentFile)
{
- if (!QFileInfo(currentFile).isFile())
+ if (!currentFile.isFileIn(m_engine->workspace()))
return;
for (int i=0; i < m_model->rowCount(); i++) {
@@ -94,9 +94,9 @@ void HostManager::followTreeSelection(const QString &currentFile)
}
}
-void HostManager::setCurrentFile(const QString &currentFile)
+void HostManager::setCurrentFile(const LiveDocument &currentFile)
{
- if (!QFileInfo(currentFile).isFile())
+ if (!currentFile.isFileIn(m_engine->workspace()))
return;
for (int i=0; i < m_model->rowCount(); i++) {
diff --git a/src/bench/hostmanager.h b/src/bench/hostmanager.h
index f37b915..68f241e 100644
--- a/src/bench/hostmanager.h
+++ b/src/bench/hostmanager.h
@@ -34,6 +34,7 @@
#include <QListView>
#include <QPointer>
+class LiveDocument;
class LiveHubEngine;
class HostModel;
class Host;
@@ -54,8 +55,8 @@ signals:
void openHostConfig(Host* host);
public slots:
- void followTreeSelection(const QString& currentFile);
- void setCurrentFile(const QString& currentFile);
+ void followTreeSelection(const LiveDocument& currentFile);
+ void setCurrentFile(const LiveDocument& currentFile);
void publishAll();
void refreshAll();
void probe(const QString &hostName);
diff --git a/src/bench/hostmodel.cpp b/src/bench/hostmodel.cpp
index a253614..a0a3b76 100644
--- a/src/bench/hostmodel.cpp
+++ b/src/bench/hostmodel.cpp
@@ -104,7 +104,7 @@ void HostModel::addHost(Host *host)
connect(host, SIGNAL(addressChanged(QString)), this, SLOT(onHostChanged()));
connect(host, SIGNAL(portChanged(int)), this, SLOT(onHostChanged()));
connect(host, SIGNAL(followTreeSelectionChanged(bool)), this, SLOT(onHostChanged()));
- connect(host, SIGNAL(currentFileChanged(QString)), this, SLOT(onHostChanged()));
+ connect(host, SIGNAL(currentFileChanged(LiveDocument)), this, SLOT(onHostChanged()));
connect(host, SIGNAL(xOffsetChanged(int)), this, SLOT(onHostChanged()));
connect(host, SIGNAL(yOffsetChanged(int)), this, SLOT(onHostChanged()));
connect(host, SIGNAL(rotationChanged(int)), this, SLOT(onHostChanged()));
diff --git a/src/bench/hostwidget.cpp b/src/bench/hostwidget.cpp
index 60ec74f..5cc646d 100644
--- a/src/bench/hostwidget.cpp
+++ b/src/bench/hostwidget.cpp
@@ -34,6 +34,7 @@
#include "host.h"
#include "livehubengine.h"
+#include <QMessageBox>
const int LABEL_STACK_INDEX=0;
const int PROGRESS_STACK_INDEX=1;
@@ -130,7 +131,7 @@ void HostWidget::setHost(Host *host)
connect(host, SIGNAL(addressChanged(QString)), this, SLOT(updateIp(QString)));
connect(host, SIGNAL(portChanged(int)), this, SLOT(updatePort(int)));
connect(host, SIGNAL(onlineChanged(bool)), this, SLOT(updateOnlineState(bool)));
- connect(host, SIGNAL(currentFileChanged(QString)), this, SLOT(updateFile(QString)));
+ connect(host, SIGNAL(currentFileChanged(LiveDocument)), this, SLOT(updateFile(LiveDocument)));
connect(host, SIGNAL(nameChanged(QString)), this, SLOT(updateName(QString)));
connect(host, SIGNAL(xOffsetChanged(int)), this, SLOT(sendXOffset(int)));
connect(host, SIGNAL(yOffsetChanged(int)), this, SLOT(sendYOffset(int)));
@@ -148,13 +149,14 @@ void HostWidget::setLiveHubEngine(LiveHubEngine *engine)
m_publisher.setWorkspace(m_engine->workspace());
connect(m_engine.data(), SIGNAL(workspaceChanged(QString)), &m_publisher, SLOT(setWorkspace(QString)));
- connect(m_engine.data(), SIGNAL(fileChanged(QString)), this, SLOT(sendDocument(QString)));
+ connect(m_engine.data(), SIGNAL(workspaceChanged(QString)), this, SLOT(refreshDocumentLabel()));
+ connect(m_engine.data(), SIGNAL(fileChanged(LiveDocument)), this, SLOT(sendDocument(LiveDocument)));
connect(m_engine.data(), SIGNAL(beginPublishWorkspace()), &m_publisher, SLOT(beginBulkSend()));
connect(m_engine.data(), SIGNAL(endPublishWorkspace()), &m_publisher, SLOT(endBulkSend()));
connect(&m_publisher, SIGNAL(needsPublishWorkspace()), this, SLOT(publishWorkspace()));
}
-void HostWidget::setCurrentFile(const QString currentFile)
+void HostWidget::setCurrentFile(const LiveDocument &currentFile)
{
m_host->setCurrentFile(currentFile);
}
@@ -192,25 +194,49 @@ void HostWidget::updatePort(int port)
QTimer::singleShot(0, this, SLOT(connectToServer()));
}
-void HostWidget::updateFile(const QString &file)
+void HostWidget::updateFile(const LiveDocument &file)
{
setUpdateFile(file);
connectAndSendFile();
}
-void HostWidget::setUpdateFile(const QString &file)
+void HostWidget::setUpdateFile(const LiveDocument &file)
{
- if (file.isEmpty()) {
- m_documentLabel->setText(tr("&lt;none&gt;"));
- m_documentLabel->setToolTip(tr("No active document. Drop one."));
- return;
+ QFont font(this->font());
+ QPalette palette(this->palette());
+ QString text;
+ QString toolTip;
+
+ if (file.isNull()) {
+ text = tr("No active document");
+ toolTip = tr("No active document. Drop one.");
+ font.setItalic(true);
+ } else {
+ text = file.relativeFilePath();
+
+ if (file.isFileIn(m_engine->workspace())) {
+ toolTip = file.absoluteFilePathIn(m_engine->workspace());
+ } else {
+ // red color from http://clrs.cc
+ palette.setColor(QPalette::Text, QColor(0xff, 0x41, 0x36));
+ toolTip = file.errorString();
+ }
}
- QString relFile = QDir(m_engine->workspace()).relativeFilePath(file);
- QFontMetrics metrics(font());
- m_documentLabel->setText(metrics.elidedText(relFile, Qt::ElideLeft, m_documentLabel->width()));
- m_documentLabel->setToolTip(relFile);
+ QFontMetrics metrics(font);
+ m_documentLabel->setFont(font);
+ m_documentLabel->setPalette(palette);
+ m_documentLabel->setText(metrics.elidedText(text, Qt::ElideLeft,
+ m_documentLabel->width()));
+ m_documentLabel->setToolTip(toolTip);
+}
+
+void HostWidget::refreshDocumentLabel()
+{
+ if (!m_host)
+ return;
+ setUpdateFile(m_host->currentFile());
}
void HostWidget::updateOnlineState(bool online)
@@ -254,7 +280,8 @@ void HostWidget::connectToServer()
void HostWidget::connectAndSendFile()
{
connectToServer();
- m_activateId = m_publisher.activateDocument(QDir(m_engine->workspace()).relativeFilePath(m_host->currentFile()));
+ if (!m_host->currentFile().isNull())
+ m_activateId = m_publisher.activateDocument(m_host->currentFile());
}
void HostWidget::onConnected()
@@ -307,12 +334,12 @@ void HostWidget::probe()
void HostWidget::publishWorkspace()
{
connectToServer();
- connect(m_engine.data(), SIGNAL(publishFile(QString)), this, SLOT(sendDocument(QString)));
+ connect(m_engine.data(), SIGNAL(publishFile(LiveDocument)), this, SLOT(sendDocument(LiveDocument)));
m_engine->publishWorkspace();
- disconnect(m_engine.data(), SIGNAL(publishFile(QString)), this, SLOT(sendDocument(QString)));
+ disconnect(m_engine.data(), SIGNAL(publishFile(LiveDocument)), this, SLOT(sendDocument(LiveDocument)));
}
-void HostWidget::sendDocument(const QString& document)
+void HostWidget::sendDocument(const LiveDocument& document)
{
if (m_publisher.state() != QAbstractSocket::ConnectedState)
return;
@@ -421,8 +448,7 @@ void HostWidget::resizeEvent(QResizeEvent *event)
{
Q_UNUSED(event);
- if (m_host)
- setUpdateFile(m_host->currentFile());
+ refreshDocumentLabel();
}
void HostWidget::showPinDialog()
@@ -446,11 +472,19 @@ void HostWidget::dragEnterEvent(QDragEnterEvent *event)
void HostWidget::dropEvent(QDropEvent *event)
{
- QUrl url(event->mimeData()->text());
-
- if (url.isLocalFile())
- m_host->setCurrentFile(url.toLocalFile());
event->acceptProposedAction();
+
+ QUrl url(event->mimeData()->text());
+ if (url.isLocalFile()) {
+ LiveDocument document = LiveDocument::resolve(m_engine->workspace(), url.toLocalFile());
+ if (!document.isNull() && document.isFileIn(m_engine->workspace())) {
+ m_host->setCurrentFile(document);
+ } else {
+ QMessageBox::warning(this, tr("Not a workspace document"),
+ tr("The dropped document is not a file in the current workspace:<br/>%1")
+ .arg(url.toString()));
+ }
+ }
}
bool HostWidget::eventFilter(QObject *object, QEvent *event)
diff --git a/src/bench/hostwidget.h b/src/bench/hostwidget.h
index b5470e7..fa08f26 100644
--- a/src/bench/hostwidget.h
+++ b/src/bench/hostwidget.h
@@ -35,6 +35,7 @@
#include <remotepublisher.h>
class Host;
+class LiveDocument;
class HostWidget : public QWidget
{
@@ -45,7 +46,7 @@ public:
void setHost(Host* host);
void setLiveHubEngine(LiveHubEngine* engine);
- void setCurrentFile(const QString currentFile);
+ void setCurrentFile(const LiveDocument &currentFile);
bool followTreeSelection() const;
signals:
@@ -68,8 +69,9 @@ private slots:
void updateName(const QString& name);
void updateIp(const QString& ip);
void updatePort(int port);
- void updateFile(const QString& file);
- void setUpdateFile(const QString& file);
+ void updateFile(const LiveDocument& file);
+ void setUpdateFile(const LiveDocument& file);
+ void refreshDocumentLabel();
void updateOnlineState(bool online);
void updateFollowTreeSelection(bool follow);
@@ -80,7 +82,7 @@ private slots:
void onDisconnected();
void onConnectionError(QAbstractSocket::SocketError error);
- void sendDocument(const QString &document);
+ void sendDocument(const LiveDocument &document);
void sendXOffset(int offset);
void sendYOffset(int offset);
diff --git a/src/bench/main.cpp b/src/bench/main.cpp
index 395d48b..ac91d64 100644
--- a/src/bench/main.cpp
+++ b/src/bench/main.cpp
@@ -273,7 +273,7 @@ void Application::parseArguments(const QStringList &arguments, Options *options)
parser.showHelp(-1);
}
options->setWorkspace(fi.absolutePath());
- options->setActiveDocument(fi.absoluteFilePath());
+ options->setActiveDocument(LiveDocument(fi.absoluteFilePath()));
} else {
qDebug() << "First argument does not ending with \".qml\". Assuming it is a workspace.";
if (!fi.exists() || !fi.isDir()) {
@@ -288,11 +288,12 @@ void Application::parseArguments(const QStringList &arguments, Options *options)
QFileInfo fi(argument);
if (argument.endsWith(".qml")) {
qDebug() << "Second 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();
+ LiveDocument document = LiveDocument::resolve(options->workspace(), argument);
+ if (document.isNull() || !document.isFileIn(options->workspace())) {
+ qWarning() << document.errorString();
parser.showHelp(-1);
}
- options->setActiveDocument(fi.absoluteFilePath());
+ options->setActiveDocument(document);
} else {
qWarning() << "If second argument is present it needs to be a QML document: " << fi.absoluteFilePath();
parser.showHelp(-1);
@@ -399,7 +400,7 @@ void MasterApplication::applyOptions(const Options &options)
qDebug() << "Ignoring attempt to set import paths after initialization.";
}
- if (!options.activeDocument().isEmpty()) {
+ if (!options.activeDocument().isNull()) {
m_window->activateDocument(options.activeDocument());
}
diff --git a/src/bench/mainwindow.cpp b/src/bench/mainwindow.cpp
index 6e3c17b..44b0436 100644
--- a/src/bench/mainwindow.cpp
+++ b/src/bench/mainwindow.cpp
@@ -77,14 +77,14 @@ MainWindow::MainWindow(QWidget *parent)
m_hub->setFilePublishingActive(true);
m_node->setWorkspaceView(m_workspace);
- connect(m_workspace, SIGNAL(pathActivated(QString)), m_hub, SLOT(setActivePath(QString)));
- connect(m_workspace, SIGNAL(pathActivated(QString)), m_hostManager, SLOT(followTreeSelection(QString)));
- connect(m_hub, SIGNAL(activateDocument(QString)), this, SLOT(updateWindowTitle()));
- connect(m_hub, SIGNAL(activateDocument(QString)), m_node, SLOT(setActiveDocument(QString)));
+ connect(m_workspace, SIGNAL(pathActivated(LiveDocument)), m_hub, SLOT(setActivePath(LiveDocument)));
+ connect(m_workspace, SIGNAL(pathActivated(LiveDocument)), m_hostManager, SLOT(followTreeSelection(LiveDocument)));
+ connect(m_hub, SIGNAL(activateDocument(LiveDocument)), this, SLOT(updateWindowTitle()));
+ connect(m_hub, SIGNAL(activateDocument(LiveDocument)), m_node, SLOT(setActiveDocument(LiveDocument)));
connect(m_node, SIGNAL(activeWindowChanged(QQuickWindow*)), this, SLOT(onActiveWindowChanged(QQuickWindow*)));
connect(m_node->qmlEngine(), SIGNAL(quit()), this, SLOT(logQuitEvent()));
connect(m_allHosts, SIGNAL(publishAll()), m_hostManager, SLOT(publishAll()));
- connect(m_allHosts, SIGNAL(currentFileChanged(QString)), m_hostManager, SLOT(setCurrentFile(QString)));
+ connect(m_allHosts, SIGNAL(currentFileChanged(LiveDocument)), m_hostManager, SLOT(setCurrentFile(LiveDocument)));
connect(m_allHosts, SIGNAL(refreshAll()), m_hostManager, SLOT(refreshAll()));
connect(m_hostManager, SIGNAL(logWidgetAdded(QDockWidget*)), this, SLOT(onLogWidgetAdded(QDockWidget*)));
connect(m_hostManager, SIGNAL(openHostConfig(Host*)), this, SLOT(openPreferences(Host*)));
@@ -240,13 +240,15 @@ void MainWindow::init()
updateRecentFolder();
- //Only set the workspace if we didn't already set it by command line
- if (m_node->activeDocument().isEmpty()) {
- if (s.contains("activeDocument")) {
- activateDocument(s.value("activeDocument").toString());
- } else {
+ //Only set the document if we didn't already set it by command line
+ if (m_node->activeDocument().isNull()) {
+ LiveDocument last;
+ if (s.contains("activeDocument"))
+ last = LiveDocument::resolve(m_workspacePath, s.value("activeDocument").toString());
+ if (!last.isNull())
+ activateDocument(last);
+ else
m_workspace->activateRootPath();
- }
}
resetImportPaths();
@@ -263,7 +265,8 @@ void MainWindow::writeSettings()
s.setValue("geometry", saveGeometry());
s.setValue("windowState", saveState());
s.setValue("workspace", m_workspacePath);
- s.setValue("activeDocument", m_node->activeDocument().toLocalFile());
+ if (!m_node->activeDocument().isNull())
+ s.setValue("activeDocument", m_node->activeDocument().relativeFilePath());
s.beginWriteArray("recentFolder");
for (int i = 0; i < m_recentFolder.count(); i++) {
@@ -300,7 +303,7 @@ void MainWindow::setupToolBar()
m_toolBar->addAction(m_resizeFit);
}
-void MainWindow::activateDocument(const QString path)
+void MainWindow::activateDocument(const LiveDocument &path)
{
m_workspace->activateDocument(path);
}
@@ -395,11 +398,11 @@ void MainWindow::logQuitEvent()
void MainWindow::updateWindowTitle()
{
setWindowFilePath(QString());
- if (m_hub->activePath().isEmpty()) {
+ if (m_hub->activePath().isNull()) {
setWindowTitle(QApplication::applicationName());
} else {
setWindowTitle(QString());
- setWindowFilePath(m_hub->activePath());
+ setWindowFilePath(m_hub->activePath().absoluteFilePathIn(m_workspacePath));
}
}
diff --git a/src/bench/mainwindow.h b/src/bench/mainwindow.h
index 87e65a8..4a7e8f1 100644
--- a/src/bench/mainwindow.h
+++ b/src/bench/mainwindow.h
@@ -39,6 +39,7 @@
class BenchQuickView;
class WorkspaceView;
class LogView;
+class LiveDocument;
class LiveRuntime;
class LiveHubEngine;
class BenchLiveNodeEngine;
@@ -57,7 +58,7 @@ class MainWindow : public QMainWindow
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
- void activateDocument(const QString path);
+ void activateDocument(const LiveDocument &path);
void setWorkspace(const QString& path, bool activateRootPath = true);
void setPluginPath(const QString& path);
void setImportPaths(const QStringList& pathList);
diff --git a/src/bench/options.cpp b/src/bench/options.cpp
index 7fa8386..5baedc2 100644
--- a/src/bench/options.cpp
+++ b/src/bench/options.cpp
@@ -85,12 +85,12 @@ void Options::setPing(bool ping)
m_ping = ping;
}
-QString Options::activeDocument() const
+LiveDocument Options::activeDocument() const
{
return m_activeDocument;
}
-void Options::setActiveDocument(const QString &activeDocument)
+void Options::setActiveDocument(const LiveDocument &activeDocument)
{
m_activeDocument = activeDocument;
}
diff --git a/src/bench/options.h b/src/bench/options.h
index 2760059..e7c84bd 100644
--- a/src/bench/options.h
+++ b/src/bench/options.h
@@ -31,6 +31,8 @@
#pragma once
+#include "livedocument.h"
+
#include <QtCore>
class Options : public QObject
@@ -58,8 +60,8 @@ public:
bool ping() const;
void setPing(bool ping);
- QString activeDocument() const;
- void setActiveDocument(const QString &activeDocument);
+ LiveDocument activeDocument() const;
+ void setActiveDocument(const LiveDocument &activeDocument);
QString workspace() const;
void setWorkspace(const QString &workspace);
@@ -88,7 +90,7 @@ private:
bool m_noRemote;
bool m_remoteOnly;
bool m_ping;
- QString m_activeDocument;
+ LiveDocument m_activeDocument;
QString m_workspace;
QString m_pluginPath;
QStringList m_importPaths;
diff --git a/src/livedocument.cpp b/src/livedocument.cpp
new file mode 100644
index 0000000..d4347cf
--- /dev/null
+++ b/src/livedocument.cpp
@@ -0,0 +1,193 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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 "livedocument.h"
+
+#include <QDebug>
+
+/*!
+ * \class LiveDocument
+ * \brief Encapsulates a relative path to a workspace document
+ * \inmodule qmllive
+ */
+
+/*!
+ * Constructs a null instance.
+ *
+ * \sa isNull(), errorString()
+ */
+LiveDocument::LiveDocument()
+{
+ m_errorString = tr("Internal error: A null LiveDocument passed");
+}
+
+/*!
+ * Constructs instance for the given \a relativeFilePath.
+ *
+ * The \a relativeFilePath MUST NOT be an empty string, it MUST be a relative
+ * path, and when resolved relatively to a directory it MUST NOT resolve to a
+ * path outside of the directory.
+ */
+LiveDocument::LiveDocument(const QString &relativeFilePath)
+{
+ LIVE_ASSERT(!relativeFilePath.isEmpty(), return);
+ LIVE_ASSERT(QDir::isRelativePath(relativeFilePath), return);
+ LIVE_ASSERT(!QDir::cleanPath(relativeFilePath).startsWith(QLatin1String("../")), return);
+
+ m_relativeFilePath = relativeFilePath;
+}
+
+/*!
+ * \fn bool LiveDocument::isNull() const
+ *
+ * Returns true if this is a null instance.
+ *
+ * A null instance has been either contructed with the default constructor or
+ * the resolve() call failed.
+ *
+ * \sa errorString()
+ */
+
+/*!
+ * \fn QString LiveDocument::errorString() const
+ *
+ * When called just after resolve(), existsIn() or isFileIn() failed, returns a
+ * descriptive message suitable for displaying in user interface. When called in
+ * other context, the result is undefined.
+ */
+
+/*!
+ * Returns \c true if this document exists in the given \a workspace directory.
+ *
+ * \sa errorString()
+ */
+bool LiveDocument::existsIn(const QDir &workspace) const
+{
+ LIVE_ASSERT(!isNull(), return false);
+
+ bool exists = QFileInfo(workspace, m_relativeFilePath).exists();
+ if (!exists) {
+ m_errorString = tr("Document '%1' does not exist in workspace '%2'")
+ .arg(m_relativeFilePath)
+ .arg(workspace.path());
+ }
+ return exists;
+}
+
+/*!
+ * Returns \c true if this document exists as a regular file (or a symbolic link
+ * to a regular file) in the given \a workspace directory.
+ *
+ * Symbolic links resolution applies.
+ *
+ * \sa errorString()
+ */
+bool LiveDocument::isFileIn(const QDir &workspace) const
+{
+ LIVE_ASSERT(!isNull(), return false);
+
+ if (!existsIn(workspace))
+ return false;
+
+ bool isFile = QFileInfo(workspace, m_relativeFilePath).isFile();
+ if (!isFile) {
+ m_errorString = tr("Document '%1' is a non-regular file in workspace '%2'")
+ .arg(m_relativeFilePath)
+ .arg(workspace.path());
+ }
+ return isFile;
+}
+
+/*!
+ * Returns the relative file path including the file name.
+ */
+QString LiveDocument::relativeFilePath() const
+{
+ LIVE_ASSERT(!isNull(), return QString());
+
+ return m_relativeFilePath;
+}
+
+/*!
+ * Returns the absolute file path within a \a workspace, including the file name.
+ */
+QString LiveDocument::absoluteFilePathIn(const QDir &workspace) const
+{
+ LIVE_ASSERT(!isNull(), return QString());
+
+ return QDir::cleanPath(workspace.absoluteFilePath(m_relativeFilePath));
+}
+
+/*!
+ * Constructs a non-null instance unless the \a filePath resolves outside of the
+ * \a workspace directory.
+ *
+ * \a filePath may be an absolute or relative file path to a file which is NOT
+ * required to exist.
+ *
+ * \sa isNull(), errorString()
+ */
+LiveDocument LiveDocument::resolve(const QDir &workspace, const QString &filePath)
+{
+ LiveDocument retv;
+
+ if (filePath.isEmpty()) {
+ qWarning() << "filePath is an empty string";
+ retv.m_errorString = tr("Not a valid file path: ''");
+ return retv;
+ }
+
+ QString relativeFilePath = workspace.relativeFilePath(filePath);
+ QString cleanPath = QDir::cleanPath(relativeFilePath);
+ if (cleanPath.isEmpty()) {
+ retv.m_relativeFilePath = QStringLiteral(".");
+ } else if (!cleanPath.startsWith(QLatin1String("../"))) {
+ retv.m_relativeFilePath = relativeFilePath;
+ } else {
+ retv.m_errorString = tr("Document path '%1' is outside the workspace directory '%2'")
+ .arg(filePath).arg(workspace.path());
+ }
+
+ return retv;
+}
+
+/*!
+ * Allows to print LiveDocument \a document via debug stream \a dbg.
+ */
+QDebug operator<<(QDebug dbg, const LiveDocument &document)
+{
+ if (document.isNull())
+ dbg << QStringLiteral("<null>");
+ else
+ dbg << document.relativeFilePath();
+
+ return dbg;
+}
diff --git a/src/livedocument.h b/src/livedocument.h
new file mode 100644
index 0000000..6aa9b0c
--- /dev/null
+++ b/src/livedocument.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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 LiveDocument
+{
+ Q_DECLARE_TR_FUNCTIONS(LiveDocument)
+
+public:
+ LiveDocument();
+ explicit LiveDocument(const QString &relativeFilePath);
+
+ bool isNull() const { return m_relativeFilePath.isEmpty(); }
+ QString errorString() const { return m_errorString; }
+
+ bool existsIn(const QDir &workspace) const;
+ bool isFileIn(const QDir &workspace) const;
+
+ QString relativeFilePath() const;
+ QString absoluteFilePathIn(const QDir &workspace) const;
+
+ static LiveDocument resolve(const QDir &workspace, const QString &filePath);
+
+ friend inline bool operator==(const LiveDocument &d1, const LiveDocument &d2)
+ { return d1.m_relativeFilePath == d2.m_relativeFilePath; }
+ friend inline bool operator!=(const LiveDocument &d1, const LiveDocument &d2)
+ { return !(d1 == d2); }
+
+private:
+ QString m_relativeFilePath;
+ mutable QString m_errorString;
+};
+
+QDebug QMLLIVESHARED_EXPORT operator<<(QDebug dbg, const LiveDocument &document);
diff --git a/src/livehubengine.cpp b/src/livehubengine.cpp
index 6db5520..b922a58 100644
--- a/src/livehubengine.cpp
+++ b/src/livehubengine.cpp
@@ -78,18 +78,18 @@ QString LiveHubEngine::workspace() const
/*!
* Sets the active document path to \a path.
- * Emits activateDocument() with the workspace relative path.
+ * Emits activateDocument() with this path.
*/
-void LiveHubEngine::setActivePath(const QString &path)
+void LiveHubEngine::setActivePath(const LiveDocument &path)
{
m_activePath = path;
- emit activateDocument(m_watcher->relativeFilePath(path));
+ emit activateDocument(m_activePath);
}
/*!
* Returns the active Document
*/
-QString LiveHubEngine::activePath() const
+LiveDocument LiveHubEngine::activePath() const
{
return m_activePath;
}
@@ -106,7 +106,7 @@ void LiveHubEngine::directoriesChanged(const QStringList &changes)
}
}
- emit activateDocument(m_watcher->relativeFilePath(m_activePath));
+ emit activateDocument(m_activePath);
}
/*!
@@ -132,10 +132,11 @@ void LiveHubEngine::publishDirectory(const QString& dirPath, bool fileChange)
if (!m_filePublishingActive) { return; }
QDirIterator iter(dirPath, QDir::Files);
while (iter.hasNext()) {
+ LiveDocument document = LiveDocument::resolve(m_watcher->directory(), iter.next());
if (fileChange)
- emit fileChanged(iter.next());
+ emit fileChanged(document);
else
- emit publishFile(iter.next());
+ emit publishFile(document);
}
}
@@ -162,21 +163,21 @@ void LiveHubEngine::setFilePublishingActive(bool on)
*/
/*!
- * \fn void LiveHubEngine::publishFile(const QString& document)
+ * \fn void LiveHubEngine::publishFile(const LiveDocument& document)
*
* This signal is emitted during publishing the directory to inform a connected
* node to publish the \a document to the remote device form the hub
*/
/*!
- * \fn void LiveHubEngine::fileChanged(const QString& document)
+ * \fn void LiveHubEngine::fileChanged(const LiveDocument& document)
*
* This signal is emitted during publishing a directory to inform a connected
* node that \a document has changed on the hub.
*/
/*!
- * \fn void LiveHubEngine::activateDocument(const QString& document)
+ * \fn void LiveHubEngine::activateDocument(const LiveDocument& document)
* The signal is emitted when the document identified by \a document has been activated
*/
diff --git a/src/livehubengine.h b/src/livehubengine.h
index 362c7db..266e07e 100644
--- a/src/livehubengine.h
+++ b/src/livehubengine.h
@@ -33,6 +33,7 @@
#include <QtCore>
+#include "livedocument.h"
#include "qmllive_global.h"
class Watcher;
@@ -46,17 +47,17 @@ public:
void setWorkspace(const QString& path);
QString workspace() const;
- QString activePath() const;
+ LiveDocument activePath() const;
public Q_SLOTS:
- void setActivePath(const QString& path);
+ void setActivePath(const LiveDocument& path);
void setFilePublishingActive(bool on);
void publishWorkspace();
Q_SIGNALS:
void beginPublishWorkspace();
void endPublishWorkspace();
- void publishFile(const QString& document);
- void fileChanged(const QString& document);
- void activateDocument(const QString& document);
+ void publishFile(const LiveDocument& document);
+ void fileChanged(const LiveDocument& document);
+ void activateDocument(const LiveDocument& document);
void workspaceChanged(const QString& workspace);
private Q_SLOTS:
void directoriesChanged(const QStringList& changes);
@@ -65,6 +66,6 @@ private:
private:
Watcher *m_watcher;
bool m_filePublishingActive;
- QString m_activePath;
+ LiveDocument m_activePath;
};
diff --git a/src/livenodeengine.cpp b/src/livenodeengine.cpp
index 1fa9e4c..594a9c8 100644
--- a/src/livenodeengine.cpp
+++ b/src/livenodeengine.cpp
@@ -119,12 +119,12 @@ public:
QDir overlay() const { return m_overlay; }
- QString reserve(const QString &document)
+ QString reserve(const LiveDocument &document)
{
QWriteLocker locker(&m_lock);
- QString overlayingPath = m_overlay.absoluteFilePath(document);
- m_mappings.insert(QUrl::fromLocalFile(m_base.absoluteFilePath(document)),
+ QString overlayingPath = document.absoluteFilePathIn(m_overlay);
+ m_mappings.insert(QUrl::fromLocalFile(document.absoluteFilePathIn(m_base)),
QUrl::fromLocalFile(overlayingPath));
return overlayingPath;
}
@@ -285,14 +285,14 @@ int LiveNodeEngine::rotation() const
}
/*!
- * Loads the given \a url onto the QML view. Clears any caches.
+ * Loads the given \a document onto the QML view. Clears any caches.
*/
-void LiveNodeEngine::loadDocument(const QUrl& url)
+void LiveNodeEngine::loadDocument(const LiveDocument& document)
{
- DEBUG << "LiveNodeEngine::loadDocument: " << url;
- m_activeFile = url;
+ DEBUG << "LiveNodeEngine::loadDocument: " << document;
+ m_activeFile = document;
- if (!m_activeFile.isEmpty())
+ if (!m_activeFile.isNull())
reloadDocument();
}
@@ -362,7 +362,8 @@ void LiveNodeEngine::reloadDocument()
emit clearLog();
- const QUrl url = queryDocumentViewer(m_activeFile);
+ const QUrl originalUrl = QUrl::fromLocalFile(m_activeFile.absoluteFilePathIn(m_workspace));
+ const QUrl url = queryDocumentViewer(originalUrl);
QScopedPointer<QQmlComponent> component(new QQmlComponent(m_qmlEngine, url));
m_object = component->create();
@@ -371,7 +372,7 @@ void LiveNodeEngine::reloadDocument()
if (component->isLoading()) {
qCritical() << "Component did not load synchronously."
<< "URL:" << url.toString()
- << "(original URL:" << m_activeFile.toString() << ")";
+ << "(original URL:" << originalUrl.toString() << ")";
} else {
emit logErrors(component->errors());
delete m_object;
@@ -444,7 +445,7 @@ void LiveNodeEngine::reloadDocument()
*
* The behavior of this function is controlled by WorkspaceOptions passed to setWorkspace().
*/
-void LiveNodeEngine::updateDocument(const QString &document, const QByteArray &content)
+void LiveNodeEngine::updateDocument(const LiveDocument &document, const QByteArray &content)
{
if (!(m_workspaceOptions & AllowUpdates)) {
return;
@@ -452,7 +453,7 @@ void LiveNodeEngine::updateDocument(const QString &document, const QByteArray &c
QString filePath = (m_workspaceOptions & UpdatesAsOverlay)
? m_overlayUrlInterceptor->reserve(document)
- : m_workspace.absoluteFilePath(document);
+ : document.absoluteFilePathIn(m_workspace);
QString dirPath = QFileInfo(filePath).absoluteDir().absolutePath();
QDir().mkpath(dirPath);
@@ -464,7 +465,7 @@ void LiveNodeEngine::updateDocument(const QString &document, const QByteArray &c
file.write(content);
file.close();
- if (!m_activeFile.isEmpty())
+ if (!m_activeFile.isNull())
delayReload();
}
@@ -495,14 +496,9 @@ QUrl LiveNodeEngine::queryDocumentViewer(const QUrl& url)
/*!
* Sets the document \a document to be shown
*/
-void LiveNodeEngine::setActiveDocument(const QString &document)
+void LiveNodeEngine::setActiveDocument(const LiveDocument &document)
{
- QUrl url;
- if (!document.isEmpty()) {
- url = QUrl::fromLocalFile(m_workspace.absoluteFilePath(document));
- }
-
- loadDocument(url);
+ loadDocument(document);
emit activateDocument(document);
}
@@ -597,9 +593,9 @@ QString LiveNodeEngine::pluginPath() const
}
/*!
- * Returns the current active document url.
+ * Returns the current active document.
*/
-QUrl LiveNodeEngine::activeDocument() const
+LiveDocument LiveNodeEngine::activeDocument() const
{
return m_activeFile;
}
@@ -650,7 +646,7 @@ void LiveNodeEngine::onSizeChanged()
}
/*!
- * \fn void LiveNodeEngine::activateDocument(const QString& document)
+ * \fn void LiveNodeEngine::activateDocument(const LiveDocument& document)
*
* The document \a document was activated
*/
diff --git a/src/livenodeengine.h b/src/livenodeengine.h
index df030e1..2b16489 100644
--- a/src/livenodeengine.h
+++ b/src/livenodeengine.h
@@ -35,6 +35,7 @@
#include <QtQuick>
#include "contentadapterinterface.h"
+#include "livedocument.h"
#include "qmllive_global.h"
class LiveRuntime;
@@ -79,7 +80,7 @@ public:
void setPluginPath(const QString& path);
QString pluginPath() const;
- QUrl activeDocument() const;
+ LiveDocument activeDocument() const;
ContentAdapterInterface *activePlugin() const;
QQuickWindow *activeWindow() const;
@@ -87,14 +88,14 @@ public Q_SLOTS:
void setXOffset(int offset);
void setYOffset(int offset);
void setRotation(int rotation);
- void setActiveDocument(const QString& document);
- void loadDocument(const QUrl& url);
+ void setActiveDocument(const LiveDocument& document);
+ void loadDocument(const LiveDocument& document);
void delayReload();
virtual void reloadDocument();
- void updateDocument(const QString &document, const QByteArray &content);
+ void updateDocument(const LiveDocument &document, const QByteArray &content);
Q_SIGNALS:
- void activateDocument(const QString& document);
+ void activateDocument(const LiveDocument& document);
void clearLog();
void logIgnoreMessages(bool on);
void documentLoaded();
@@ -105,7 +106,7 @@ Q_SIGNALS:
protected:
virtual void initPlugins();
QList<ContentAdapterInterface*> m_plugins;
- QUrl m_activeFile;
+ LiveDocument m_activeFile;
LiveRuntime *m_runtime;
private Q_SLOTS:
diff --git a/src/qmllive_global.h b/src/qmllive_global.h
index ce64734..f78924a 100644
--- a/src/qmllive_global.h
+++ b/src/qmllive_global.h
@@ -40,4 +40,20 @@
# define QMLLIVESHARED_EXPORT Q_DECL_IMPORT
#endif
+#if defined(QMLLIVE_VERSION)
+# define QMLLIVE_SOURCE
+#endif
+
+#if defined(QMLLIVE_SOURCE)
+# if !defined(QT_NO_DEBUG) || defined(QT_FORCE_ASSERTS)
+# define LIVE_ASSERT(cond, action) Q_ASSERT(cond)
+# else
+# define LIVE_ASSERT(cond, action) if (cond) {} else { \
+ QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).critical() \
+ << "Assertion \"" #cond "\" failed"; \
+ action; \
+ } do {} while (0)
+# endif
+#endif
+
#endif // QMLLIVELIB_GLOBAL_H
diff --git a/src/remotepublisher.cpp b/src/remotepublisher.cpp
index c1e1982..08908a8 100644
--- a/src/remotepublisher.cpp
+++ b/src/remotepublisher.cpp
@@ -31,6 +31,7 @@
#include "remotepublisher.h"
#include "ipc/ipcclient.h"
+#include "livedocument.h"
#include "livehubengine.h"
#ifdef QMLLIVE_DEBUG
@@ -91,9 +92,9 @@ void RemotePublisher::registerHub(LiveHubEngine *hub)
disconnect(m_hub);
}
m_hub = hub;
- connect(hub, SIGNAL(activateDocument(QString)), this, SLOT(activateDocument(QString)));
- connect(hub, SIGNAL(fileChanged(QString)), this, SLOT(sendDocument(QString)));
- connect(hub, SIGNAL(publishFile(QString)), this, SLOT(sendDocument(QString)));
+ connect(hub, SIGNAL(activateDocument(LiveDocument)), this, SLOT(activateDocument(LiveDocument)));
+ connect(hub, SIGNAL(fileChanged(LiveDocument)), this, SLOT(sendDocument(LiveDocument)));
+ connect(hub, SIGNAL(publishFile(LiveDocument)), this, SLOT(sendDocument(LiveDocument)));
connect(this, SIGNAL(needsPublishWorkspace()), hub, SLOT(publishWorkspace()));
connect(hub, SIGNAL(beginPublishWorkspace()), this, SLOT(beginBulkSend()));
connect(hub, SIGNAL(endPublishWorkspace()), this, SLOT(endBulkSend()));
@@ -137,12 +138,12 @@ void RemotePublisher::disconnectFromServer()
* Send "activateDocument(QString)" to IPC-server on activate document.
* \a document defines the Document which should be activated
*/
-QUuid RemotePublisher::activateDocument(const QString &document)
+QUuid RemotePublisher::activateDocument(const LiveDocument &document)
{
DEBUG << "RemotePublisher::activateDocument" << document;
QByteArray bytes;
QDataStream out(&bytes, QIODevice::WriteOnly);
- out << document;
+ out << document.relativeFilePath();
return m_ipc->send("activateDocument(QString)", bytes);
}
@@ -165,10 +166,10 @@ QUuid RemotePublisher::endBulkSend()
}
/*!
- * Sends "sendDocument(QString)" using \a document as path to the document to be
+ * Sends "sendDocument(QString)" using \a document to identify the document to be
*send to via IPC.
*/
-QUuid RemotePublisher::sendDocument(const QString& document)
+QUuid RemotePublisher::sendDocument(const LiveDocument& document)
{
DEBUG << "RemotePublisher::sendDocument" << document;
return sendWholeDocument(document);
@@ -224,10 +225,10 @@ QUuid RemotePublisher::setRotation(int rotation)
/*!
Sends the \e sendWholeDocument with \a document as argument via IPC
*/
-QUuid RemotePublisher::sendWholeDocument(const QString& document)
+QUuid RemotePublisher::sendWholeDocument(const LiveDocument& document)
{
DEBUG << "RemotePublisher::sendWholeDocument" << document;
- QFile file(document);
+ QFile file(document.absoluteFilePathIn(m_workspace));
if (!file.open(QIODevice::ReadOnly)) {
qWarning() << "ERROR: can't open file: " << document;
return QUuid();
@@ -236,7 +237,7 @@ QUuid RemotePublisher::sendWholeDocument(const QString& document)
QByteArray bytes;
QDataStream out(&bytes, QIODevice::WriteOnly);
- out << m_workspace.relativeFilePath(document);
+ out << document.relativeFilePath();
out << data;
return m_ipc->send("sendDocument(QString,QByteArray)", bytes);
}
diff --git a/src/remotepublisher.h b/src/remotepublisher.h
index 8d69f9b..9df2601 100644
--- a/src/remotepublisher.h
+++ b/src/remotepublisher.h
@@ -36,6 +36,7 @@
#include "qmllive_global.h"
+class LiveDocument;
class LiveHubEngine;
class IpcClient;
@@ -64,10 +65,10 @@ Q_SIGNALS:
public Q_SLOTS:
void setWorkspace(const QString &path);
void disconnectFromServer();
- QUuid activateDocument(const QString& document);
+ QUuid activateDocument(const LiveDocument& document);
QUuid beginBulkSend();
QUuid endBulkSend();
- QUuid sendDocument(const QString& document);
+ QUuid sendDocument(const LiveDocument& document);
QUuid checkPin(const QString& pin);
QUuid setXOffset(int offset);
QUuid setYOffset(int offset);
@@ -75,7 +76,7 @@ public Q_SLOTS:
private Q_SLOTS:
void handleCall(const QString &method, const QByteArray &content);
- QUuid sendWholeDocument(const QString &document);
+ QUuid sendWholeDocument(const LiveDocument &document);
void onSentSuccessfully(const QUuid& uuid);
void onSendingError(const QUuid& uuid, QAbstractSocket::SocketError socketError);
diff --git a/src/remotereceiver.cpp b/src/remotereceiver.cpp
index ebfa989..d434a5b 100644
--- a/src/remotereceiver.cpp
+++ b/src/remotereceiver.cpp
@@ -227,13 +227,13 @@ void RemoteReceiver::handleCall(const QString &method, const QByteArray &content
QDataStream in(content);
in >> document;
in >> data;
- emit updateDocument(document, data);
+ emit updateDocument(LiveDocument(document), data);
} else if (method == "activateDocument(QString)") {
QString document;
QDataStream in(content);
in >> document;
qDebug() << "\tactivate document: " << document;
- emit activateDocument(document);
+ emit activateDocument(LiveDocument(document));
} else if (method == "ping()") {
if (m_client)
m_client->send("pong()", QByteArray());
@@ -249,8 +249,8 @@ void RemoteReceiver::registerNode(LiveNodeEngine *node)
m_node = node;
connect(m_node, SIGNAL(logErrors(QList<QQmlError>)), this, SLOT(appendToLog(QList<QQmlError>)));
connect(m_node, SIGNAL(clearLog()), this, SLOT(clearLog()));
- connect(this, SIGNAL(activateDocument(QString)), m_node, SLOT(setActiveDocument(QString)));
- connect(this, SIGNAL(updateDocument(QString,QByteArray)), m_node, SLOT(updateDocument(QString,QByteArray)));
+ connect(this, SIGNAL(activateDocument(LiveDocument)), m_node, SLOT(setActiveDocument(LiveDocument)));
+ connect(this, SIGNAL(updateDocument(LiveDocument,QByteArray)), m_node, SLOT(updateDocument(LiveDocument,QByteArray)));
connect(this, SIGNAL(xOffsetChanged(int)), m_node, SLOT(setXOffset(int)));
connect(this, SIGNAL(yOffsetChanged(int)), m_node, SLOT(setYOffset(int)));
connect(this, SIGNAL(rotationChanged(int)), m_node, SLOT(setRotation(int)));
@@ -341,7 +341,7 @@ void RemoteReceiver::clearLog()
}
/*!
- * \fn void RemoteReceiver::activateDocument(const QString& document)
+ * \fn void RemoteReceiver::activateDocument(const LiveDocument& document)
*
* This signal is emitted when the remote active document \a document has changed
*/
@@ -410,7 +410,7 @@ void RemoteReceiver::clearLog()
*/
/*!
- * \fn void RemoteReceiver::updateDocument(const QString &document, const QByteArray &content)
+ * \fn void RemoteReceiver::updateDocument(const LiveDocument &document, const QByteArray &content)
*
* This signal is emitted to notify that a \a document has changed its \a content
*/
diff --git a/src/remotereceiver.h b/src/remotereceiver.h
index aba3eed..6877f50 100644
--- a/src/remotereceiver.h
+++ b/src/remotereceiver.h
@@ -38,6 +38,7 @@
#include "qmllive_global.h"
+class LiveDocument;
class LiveNodeEngine;
class IpcServer;
class IpcClient;
@@ -80,7 +81,7 @@ public:
void setMaxConnections(int max);
Q_SIGNALS:
- void activateDocument(const QString& document);
+ void activateDocument(const LiveDocument& document);
void reload();
void clientConnected(const QHostAddress& address);
void clientDisconnected(const QHostAddress& address);
@@ -91,7 +92,7 @@ Q_SIGNALS:
void beginBulkUpdate();
void endBulkUpdate();
void updateDocumentsOnConnectFinished(bool ok);
- void updateDocument(const QString &document, const QByteArray &content);
+ void updateDocument(const LiveDocument &document, const QByteArray &content);
private Q_SLOTS:
void handleCall(const QString& method, const QByteArray& content);
diff --git a/src/runtime/main.cpp b/src/runtime/main.cpp
index e741768..3058e24 100644
--- a/src/runtime/main.cpp
+++ b/src/runtime/main.cpp
@@ -189,12 +189,13 @@ int main(int argc, char** argv)
engine.setFallbackView(&fallbackView);
engine.setWorkspace(options.workspace, workspaceOptions);
engine.setPluginPath(options.pluginPath);
- engine.loadDocument(QUrl("qrc:/qml/qmlsplash/splash-qt5.qml"));
RemoteReceiver receiver;
receiver.registerNode(&engine);
if (!receiver.listen(options.ipcPort, connectionOptions))
return EXIT_FAILURE;
+ fallbackView.setSource(QUrl("qrc:/qml/qmlsplash/splash-qt5.qml"));
+
int ret = app.exec();
return ret;
diff --git a/src/src.pri b/src/src.pri
index 8a629e6..1af18e4 100644
--- a/src/src.pri
+++ b/src/src.pri
@@ -8,6 +8,7 @@ DEFINES += NO_LIBRSYNC
SOURCES += \
$$PWD/watcher.cpp \
+ $$PWD/livedocument.cpp \
$$PWD/livehubengine.cpp \
$$PWD/livenodeengine.cpp \
$$PWD/qmlhelper.cpp \
@@ -22,6 +23,7 @@ SOURCES += \
$$PWD/fontadapter.cpp
public_headers += \
+ $$PWD/livedocument.h \
$$PWD/livehubengine.h \
$$PWD/livenodeengine.h \
$$PWD/qmlhelper.h \
diff --git a/src/watcher.cpp b/src/watcher.cpp
index c97fa8f..37f625f 100644
--- a/src/watcher.cpp
+++ b/src/watcher.cpp
@@ -105,15 +105,6 @@ void Watcher::addDirectoriesRecursively(const QString &path)
}
-/*!
- Returns the given path relative to the watcher's Directory
- /sa setDirectory, directory()
- */
-QString Watcher::relativeFilePath(const QString &path)
-{
- return m_rootDir.relativeFilePath(path);
-}
-
void Watcher::recordChange(const QString &path)
{
// qDebug() << "Watcher::recordChange: " << path;
diff --git a/src/watcher.h b/src/watcher.h
index 67f39ae..a17e28a 100644
--- a/src/watcher.h
+++ b/src/watcher.h
@@ -40,7 +40,6 @@ public:
explicit Watcher(QObject *parent = 0);
void setDirectory(const QString& path);
QString directory() const;
- QString relativeFilePath(const QString& path);
private Q_SLOTS:
void recordChange(const QString &path);
void notifyChanges();
diff --git a/src/widgets/workspaceview.cpp b/src/widgets/workspaceview.cpp
index d6523ab..10b9f2b 100644
--- a/src/widgets/workspaceview.cpp
+++ b/src/widgets/workspaceview.cpp
@@ -85,17 +85,17 @@ void WorkspaceView::setRootPath(const QString &dirPath)
/*!
* Activates the document by the given \a path
*/
-void WorkspaceView::activateDocument(const QString &path)
+void WorkspaceView::activateDocument(const LiveDocument &path)
{
//qDebug() << "WorkspaceView::activateDocument" << path;
- QModelIndex index = m_model->index(path);
+ QModelIndex index = m_model->index(path.absoluteFilePathIn(rootPath()));
selectIndex(index);
}
void WorkspaceView::activateRootPath()
{
selectIndex(m_rootIndex);
- emit pathActivated(m_model->rootPath());
+ emit pathActivated(LiveDocument(QStringLiteral(".")));
}
void WorkspaceView::goUp()
@@ -110,7 +110,7 @@ void WorkspaceView::goUp()
/*!
* Returns the active, selected document.
*/
-QString WorkspaceView::activeDocument() const
+LiveDocument WorkspaceView::activeDocument() const
{
return m_currentDocument;
}
@@ -140,8 +140,8 @@ void WorkspaceView::indexActivated(const QModelIndex &index)
QString path = m_model->filePath(index);
- m_currentDocument = path;
- emit pathActivated(path);
+ m_currentDocument = LiveDocument::resolve(m_model->rootDirectory(), path);
+ emit pathActivated(m_currentDocument);
}
void WorkspaceView::selectIndex(const QModelIndex &index)
diff --git a/src/widgets/workspaceview.h b/src/widgets/workspaceview.h
index 4e1c9c3..6058b04 100644
--- a/src/widgets/workspaceview.h
+++ b/src/widgets/workspaceview.h
@@ -31,6 +31,8 @@
#pragma once
+#include "livedocument.h"
+
#include <QtGui>
#include <QtWidgets>
@@ -41,19 +43,19 @@ class WorkspaceView : public QWidget
Q_OBJECT
public:
explicit WorkspaceView(QWidget *parent = 0);
- QString activeDocument() const;
+ LiveDocument activeDocument() const;
QString rootPath() const;
void setDirectoriesSelectable(bool enabled);
bool directoriesSelectable() const;
public Q_SLOTS:
void setRootPath(const QString& dirPath);
- void activateDocument(const QString& path);
+ void activateDocument(const LiveDocument& path);
void activateRootPath();
void goUp();
Q_SIGNALS:
- void pathActivated(const QString& path);
+ void pathActivated(const LiveDocument& path);
private Q_SLOTS:
void indexActivated(const QModelIndex& index);
@@ -63,5 +65,5 @@ private:
QTreeView *m_view;
FileSystemModel *m_model;
QModelIndex m_rootIndex;
- QString m_currentDocument;
+ LiveDocument m_currentDocument;
};