WIP: Allow refreshing root in file browser
This commit is contained in:
parent
0ee0dbd10a
commit
f8d71492e5
|
@ -53,7 +53,7 @@ enum class SyncthingItemType { Unknown, File, Directory };
|
||||||
|
|
||||||
struct LIB_SYNCTHING_CONNECTOR_EXPORT SyncthingItem {
|
struct LIB_SYNCTHING_CONNECTOR_EXPORT SyncthingItem {
|
||||||
QString name;
|
QString name;
|
||||||
CppUtilities::DateTime modificationTime;
|
CppUtilities::DateTime modificationTime = CppUtilities::DateTime();
|
||||||
std::size_t size = std::size_t();
|
std::size_t size = std::size_t();
|
||||||
SyncthingItemType type = SyncthingItemType::Unknown;
|
SyncthingItemType type = SyncthingItemType::Unknown;
|
||||||
std::vector<SyncthingItem> children;
|
std::vector<SyncthingItem> children;
|
||||||
|
@ -254,7 +254,7 @@ public Q_SLOTS:
|
||||||
public:
|
public:
|
||||||
// methods to GET or POST information from/to Syncthing (non-slots)
|
// methods to GET or POST information from/to Syncthing (non-slots)
|
||||||
QMetaObject::Connection browse(
|
QMetaObject::Connection browse(
|
||||||
const QString &dirId, const QString &prefix, int level, std::function<void(std::vector<SyncthingItem> &&)> &&callback);
|
const QString &dirId, const QString &prefix, int level, std::function<void(std::vector<SyncthingItem> &&, QString &&error)> &&callback);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void newConfig(const QJsonObject &rawConfig);
|
void newConfig(const QJsonObject &rawConfig);
|
||||||
|
@ -369,7 +369,7 @@ private Q_SLOTS:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// handler to evaluate results from request...() methods
|
// handler to evaluate results from request...() methods
|
||||||
void readBrowse(const QString &dirId, int levels, std::function<void(std::vector<SyncthingItem> &&)> &&callback);
|
void readBrowse(const QString &dirId, int levels, std::function<void (std::vector<SyncthingItem> &&, QString &&)> &&callback);
|
||||||
|
|
||||||
// internal helper methods
|
// internal helper methods
|
||||||
struct Reply {
|
struct Reply {
|
||||||
|
|
|
@ -1590,8 +1590,7 @@ void SyncthingConnection::readRevert()
|
||||||
* consume results of a specific request. Errors are still reported via the error() signal so there's no extra error handling
|
* consume results of a specific request. Errors are still reported via the error() signal so there's no extra error handling
|
||||||
* required. Note that \a callback is *not* invoked in the error case.
|
* required. Note that \a callback is *not* invoked in the error case.
|
||||||
*/
|
*/
|
||||||
QMetaObject::Connection SyncthingConnection::browse(
|
QMetaObject::Connection SyncthingConnection::browse(const QString &dirId, const QString &prefix, int levels, std::function<void (std::vector<SyncthingItem> &&, QString &&)> &&callback)
|
||||||
const QString &dirId, const QString &prefix, int levels, std::function<void(std::vector<SyncthingItem> &&)> &&callback)
|
|
||||||
{
|
{
|
||||||
auto query = QUrlQuery();
|
auto query = QUrlQuery();
|
||||||
query.addQueryItem(QStringLiteral("folder"), formatQueryItem(dirId));
|
query.addQueryItem(QStringLiteral("folder"), formatQueryItem(dirId));
|
||||||
|
@ -1643,9 +1642,10 @@ static void readSyncthingItems(const QJsonArray &array, std::vector<SyncthingIte
|
||||||
/// \endcond
|
/// \endcond
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Reads the response of browse() and reports results via the specified \a callback or emits error() in case of an error.
|
* \brief Reads the response of browse() and reports results via the specified \a callback. Emits error() in case of an error.
|
||||||
|
* \remarks The \a callback is also emitted in the error case (with the error message as second parameter and an empty list of items).
|
||||||
*/
|
*/
|
||||||
void SyncthingConnection::readBrowse(const QString &dirId, int levels, std::function<void(std::vector<SyncthingItem> &&)> &&callback)
|
void SyncthingConnection::readBrowse(const QString &dirId, int levels, std::function<void (std::vector<SyncthingItem> &&, QString &&)> &&callback)
|
||||||
{
|
{
|
||||||
auto const [reply, response] = prepareReply();
|
auto const [reply, response] = prepareReply();
|
||||||
if (!reply) {
|
if (!reply) {
|
||||||
|
@ -1657,18 +1657,25 @@ void SyncthingConnection::readBrowse(const QString &dirId, int levels, std::func
|
||||||
auto jsonError = QJsonParseError();
|
auto jsonError = QJsonParseError();
|
||||||
const auto replyDoc = QJsonDocument::fromJson(response, &jsonError);
|
const auto replyDoc = QJsonDocument::fromJson(response, &jsonError);
|
||||||
if (jsonError.error != QJsonParseError::NoError) {
|
if (jsonError.error != QJsonParseError::NoError) {
|
||||||
emit error(tr("Unable to parse response for browsing \"%1\": ").arg(dirId) + jsonError.errorString(), SyncthingErrorCategory::Parsing,
|
auto errorMessage = tr("Unable to parse response for browsing \"%1\": ").arg(dirId) + jsonError.errorString();
|
||||||
QNetworkReply::NoError);
|
emit error(errorMessage, SyncthingErrorCategory::Parsing, QNetworkReply::NoError);
|
||||||
|
if (callback) {
|
||||||
|
callback(std::move(items), std::move(errorMessage));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
readSyncthingItems(replyDoc.array(), items, 0, levels);
|
readSyncthingItems(replyDoc.array(), items, 0, levels);
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback(std::move(items));
|
callback(std::move(items), QString());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
emitError(tr("Unable to browse \"%1\": ").arg(dirId), SyncthingErrorCategory::SpecificRequest, reply);
|
auto errorMessage = tr("Unable to browse \"%1\": ").arg(dirId);
|
||||||
|
emitError(errorMessage, SyncthingErrorCategory::SpecificRequest, reply);
|
||||||
|
if (callback) {
|
||||||
|
callback(std::move(items), std::move(errorMessage));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,20 +8,25 @@
|
||||||
|
|
||||||
#include <QStringBuilder>
|
#include <QStringBuilder>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace CppUtilities;
|
using namespace CppUtilities;
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
|
|
||||||
SyncthingFileModel::SyncthingFileModel(SyncthingConnection &connection, const QString &dirId, QObject *parent)
|
SyncthingFileModel::SyncthingFileModel(SyncthingConnection &connection, const SyncthingDir &dir, QObject *parent)
|
||||||
: SyncthingModel(connection, parent)
|
: SyncthingModel(connection, parent)
|
||||||
, m_connection(connection)
|
, m_connection(connection)
|
||||||
, m_dirId(dirId)
|
, m_dirId(dir.id)
|
||||||
|
, m_root({ .name = dir.displayName(), .modificationTime = dir.lastFileTime, .size = dir.globalStats.bytes, .type = SyncthingItemType::Directory })
|
||||||
{
|
{
|
||||||
m_connection.browse(m_dirId, QString(), 1, [this](std::vector<SyncthingItem> &&items) {
|
m_connection.browse(m_dirId, QString(), 1, [this](std::vector<SyncthingItem> &&items, QString &&errorMessage) {
|
||||||
|
Q_UNUSED(errorMessage)
|
||||||
const auto last = items.size() - 1;
|
const auto last = items.size() - 1;
|
||||||
beginInsertRows(QModelIndex(), 0, last < std::numeric_limits<int>::max() ? static_cast<int>(last) : std::numeric_limits<int>::max());
|
beginInsertRows(index(0, 0), 0, last < std::numeric_limits<int>::max() ? static_cast<int>(last) : std::numeric_limits<int>::max());
|
||||||
m_items = std::move(items);
|
m_root.children = std::move(items);
|
||||||
|
m_root.childrenPopulated = true;
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -49,15 +54,13 @@ QModelIndex SyncthingFileModel::index(int row, int column, const QModelIndex &pa
|
||||||
if (row < 0 || column < 0 || column > 2) {
|
if (row < 0 || column < 0 || column > 2) {
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parent.isValid()) {
|
if (!parent.isValid()) {
|
||||||
if (static_cast<std::size_t>(row) >= m_items.size()) {
|
return static_cast<std::size_t>(row) ? QModelIndex() : createIndex(row, column, &m_root);
|
||||||
return QModelIndex();
|
|
||||||
}
|
|
||||||
return createIndex(row, column, &m_items[static_cast<std::size_t>(row)]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto *const parentItem = reinterpret_cast<SyncthingItem *>(parent.internalPointer());
|
auto *const parentItem = reinterpret_cast<SyncthingItem *>(parent.internalPointer());
|
||||||
|
if (!parentItem) {
|
||||||
|
return QModelIndex();
|
||||||
|
}
|
||||||
auto &items = parentItem->children;
|
auto &items = parentItem->children;
|
||||||
if (static_cast<std::size_t>(row) >= items.size()) {
|
if (static_cast<std::size_t>(row) >= items.size()) {
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
|
@ -67,6 +70,30 @@ QModelIndex SyncthingFileModel::index(int row, int column, const QModelIndex &pa
|
||||||
return createIndex(row, column, &item);
|
return createIndex(row, column, &item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QModelIndex SyncthingFileModel::index(const QString &path) const
|
||||||
|
{
|
||||||
|
auto parts = path.split(QChar('/'), Qt::SkipEmptyParts);
|
||||||
|
auto res = index(0, 0);
|
||||||
|
auto *parent = &m_root;
|
||||||
|
for (const auto &part : parts) {
|
||||||
|
auto foundPart = false;
|
||||||
|
for (const auto &child : parent->children) {
|
||||||
|
if (child.name == part) {
|
||||||
|
parent = &child;
|
||||||
|
res = index(static_cast<int>(child.index), 0, res);
|
||||||
|
foundPart = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!foundPart) {
|
||||||
|
res = QModelIndex();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cerr << "index for path " << path.toStdString() << ": " << this->path(res).toStdString() << '\n';
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
QString SyncthingFileModel::path(const QModelIndex &index) const
|
QString SyncthingFileModel::path(const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
auto res = QString();
|
auto res = QString();
|
||||||
|
@ -77,6 +104,10 @@ QString SyncthingFileModel::path(const QModelIndex &index) const
|
||||||
auto size = QString::size_type();
|
auto size = QString::size_type();
|
||||||
parts.reserve(reinterpret_cast<SyncthingItem *>(index.internalPointer())->level + 1);
|
parts.reserve(reinterpret_cast<SyncthingItem *>(index.internalPointer())->level + 1);
|
||||||
for (auto i = index; i.isValid(); i = i.parent()) {
|
for (auto i = index; i.isValid(); i = i.parent()) {
|
||||||
|
const auto *const item = reinterpret_cast<SyncthingItem *>(i.internalPointer());
|
||||||
|
if (item == &m_root) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
parts.append(reinterpret_cast<SyncthingItem *>(i.internalPointer())->name);
|
parts.append(reinterpret_cast<SyncthingItem *>(i.internalPointer())->name);
|
||||||
size += parts.back().size();
|
size += parts.back().size();
|
||||||
}
|
}
|
||||||
|
@ -94,10 +125,10 @@ QModelIndex SyncthingFileModel::parent(const QModelIndex &child) const
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
}
|
}
|
||||||
auto *const childItem = reinterpret_cast<SyncthingItem *>(child.internalPointer());
|
auto *const childItem = reinterpret_cast<SyncthingItem *>(child.internalPointer());
|
||||||
if (!childItem->parent) {
|
if (!childItem) {
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
}
|
}
|
||||||
return createIndex(static_cast<int>(childItem->index), 0, childItem->parent);
|
return !childItem->parent ? QModelIndex() : createIndex(static_cast<int>(childItem->index), 0, childItem->parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant SyncthingFileModel::headerData(int section, Qt::Orientation orientation, int role) const
|
QVariant SyncthingFileModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
|
@ -192,7 +223,7 @@ int SyncthingFileModel::rowCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
auto res = std::size_t();
|
auto res = std::size_t();
|
||||||
if (!parent.isValid()) {
|
if (!parent.isValid()) {
|
||||||
res = m_items.size();
|
res = 1;
|
||||||
} else {
|
} else {
|
||||||
auto *const parentItem = reinterpret_cast<SyncthingItem *>(parent.internalPointer());
|
auto *const parentItem = reinterpret_cast<SyncthingItem *>(parent.internalPointer());
|
||||||
res = parentItem->childrenPopulated || parentItem->type != SyncthingItemType::Directory ? parentItem->children.size() : 1;
|
res = parentItem->childrenPopulated || parentItem->type != SyncthingItemType::Directory ? parentItem->children.size() : 1;
|
||||||
|
@ -230,7 +261,7 @@ void SyncthingFileModel::fetchMore(const QModelIndex &parent)
|
||||||
if (!parent.isValid()) {
|
if (!parent.isValid()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_fetchQueue.append(parent);
|
m_fetchQueue.append(path(parent));
|
||||||
if (m_fetchQueue.size() == 1) {
|
if (m_fetchQueue.size() == 1) {
|
||||||
processFetchQueue();
|
processFetchQueue();
|
||||||
}
|
}
|
||||||
|
@ -261,19 +292,32 @@ void SyncthingFileModel::processFetchQueue()
|
||||||
if (m_fetchQueue.isEmpty()) {
|
if (m_fetchQueue.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto &parent = m_fetchQueue.front();
|
const auto &path = m_fetchQueue.front();
|
||||||
m_pendingRequest = m_connection.browse(m_dirId, path(parent), 1, [this, parent](std::vector<SyncthingItem> &&items) {
|
m_pendingRequest = m_connection.browse(m_dirId, path, 1, [this, p = path](std::vector<SyncthingItem> &&items, QString &&errorMessage) {
|
||||||
auto *const parentItem = reinterpret_cast<SyncthingItem *>(parent.internalPointer());
|
Q_UNUSED(errorMessage)
|
||||||
addLevel(items, parentItem->level);
|
m_fetchQueue.removeAll(p);
|
||||||
beginRemoveRows(parent, 0, static_cast<int>(parentItem->children.size() - 1));
|
|
||||||
parentItem->children.clear();
|
const auto refreshedIndex = index(p);
|
||||||
endRemoveRows();
|
if (!refreshedIndex.isValid()) {
|
||||||
const auto last = items.size() - 1;
|
return;
|
||||||
beginInsertRows(parent, 0, last < std::numeric_limits<int>::max() ? static_cast<int>(last) : std::numeric_limits<int>::max());
|
}
|
||||||
parentItem->children = std::move(items);
|
auto *const refreshedItem = reinterpret_cast<SyncthingItem *>(refreshedIndex.internalPointer());
|
||||||
parentItem->childrenPopulated = true;
|
if (!refreshedItem->children.empty()) {
|
||||||
endInsertRows();
|
beginRemoveRows(refreshedIndex, 0, static_cast<int>(refreshedItem->children.size() - 1));
|
||||||
m_fetchQueue.removeAll(parent);
|
refreshedItem->children.clear();
|
||||||
|
endRemoveRows();
|
||||||
|
}
|
||||||
|
if (!items.empty()) {
|
||||||
|
const auto last = items.size() - 1;
|
||||||
|
addLevel(items, refreshedItem->level);
|
||||||
|
for (auto &item : items) {
|
||||||
|
item.parent = refreshedItem;
|
||||||
|
}
|
||||||
|
beginInsertRows(refreshedIndex, 0, last < std::numeric_limits<int>::max() ? static_cast<int>(last) : std::numeric_limits<int>::max());
|
||||||
|
refreshedItem->children = std::move(items);
|
||||||
|
refreshedItem->childrenPopulated = true;
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
processFetchQueue();
|
processFetchQueue();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,23 +3,24 @@
|
||||||
|
|
||||||
#include "./syncthingmodel.h"
|
#include "./syncthingmodel.h"
|
||||||
|
|
||||||
|
#include <syncthingconnector/syncthingconnection.h>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
|
|
||||||
struct SyncthingItem;
|
|
||||||
|
|
||||||
class LIB_SYNCTHING_MODEL_EXPORT SyncthingFileModel : public SyncthingModel {
|
class LIB_SYNCTHING_MODEL_EXPORT SyncthingFileModel : public SyncthingModel {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
enum SyncthingFileModelRole { NameRole = SyncthingModelUserRole + 1, SizeRole, ModificationTimeRole, Actions, ActionNames, ActionIcons };
|
enum SyncthingFileModelRole { NameRole = SyncthingModelUserRole + 1, SizeRole, ModificationTimeRole, Actions, ActionNames, ActionIcons };
|
||||||
|
|
||||||
explicit SyncthingFileModel(SyncthingConnection &connection, const QString &dirId, QObject *parent = nullptr);
|
explicit SyncthingFileModel(SyncthingConnection &connection, const SyncthingDir &dir, QObject *parent = nullptr);
|
||||||
~SyncthingFileModel() override;
|
~SyncthingFileModel() override;
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
QHash<int, QByteArray> roleNames() const override;
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
|
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
QModelIndex index(const QString &path) const;
|
||||||
QModelIndex parent(const QModelIndex &child) const override;
|
QModelIndex parent(const QModelIndex &child) const override;
|
||||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
|
@ -44,9 +45,9 @@ private:
|
||||||
private:
|
private:
|
||||||
SyncthingConnection &m_connection;
|
SyncthingConnection &m_connection;
|
||||||
QString m_dirId;
|
QString m_dirId;
|
||||||
QModelIndexList m_fetchQueue;
|
QStringList m_fetchQueue;
|
||||||
QMetaObject::Connection m_pendingRequest;
|
QMetaObject::Connection m_pendingRequest;
|
||||||
mutable std::vector<SyncthingItem> m_items;
|
SyncthingItem m_root;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
|
@ -276,7 +276,7 @@ QString StatusIconSettings::toString() const
|
||||||
|
|
||||||
StatusIcons::StatusIcons(const StatusIconSettings &settings)
|
StatusIcons::StatusIcons(const StatusIconSettings &settings)
|
||||||
: disconnected(
|
: disconnected(
|
||||||
QIcon(renderSvgImage(makeSyncthingIcon(settings.disconnectedColor, StatusEmblem::None, settings.strokeWidth), settings.renderSize)))
|
QIcon(renderSvgImage(makeSyncthingIcon(settings.disconnectedColor, StatusEmblem::None, settings.strokeWidth), settings.renderSize)))
|
||||||
, idling(QIcon(renderSvgImage(makeSyncthingIcon(settings.idleColor, StatusEmblem::None, settings.strokeWidth), settings.renderSize)))
|
, idling(QIcon(renderSvgImage(makeSyncthingIcon(settings.idleColor, StatusEmblem::None, settings.strokeWidth), settings.renderSize)))
|
||||||
, scanninig(QIcon(renderSvgImage(makeSyncthingIcon(settings.scanningColor, StatusEmblem::Scanning, settings.strokeWidth), settings.renderSize)))
|
, scanninig(QIcon(renderSvgImage(makeSyncthingIcon(settings.scanningColor, StatusEmblem::Scanning, settings.strokeWidth), settings.renderSize)))
|
||||||
, notify(QIcon(renderSvgImage(makeSyncthingIcon(settings.warningColor, StatusEmblem::Alert, settings.strokeWidth), settings.renderSize)))
|
, notify(QIcon(renderSvgImage(makeSyncthingIcon(settings.warningColor, StatusEmblem::Alert, settings.strokeWidth), settings.renderSize)))
|
||||||
|
|
|
@ -88,7 +88,7 @@ QDialog *browseRemoteFilesDialog(Data::SyncthingConnection &connection, const Da
|
||||||
dlg->setAttribute(Qt::WA_DeleteOnClose);
|
dlg->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
|
||||||
// setup model/view
|
// setup model/view
|
||||||
auto model = new Data::SyncthingFileModel(connection, dir.id, &connection);
|
auto model = new Data::SyncthingFileModel(connection, dir, &connection);
|
||||||
auto view = new QTreeView(dlg);
|
auto view = new QTreeView(dlg);
|
||||||
view->setModel(model);
|
view->setModel(model);
|
||||||
view->setContextMenuPolicy(Qt::CustomContextMenu);
|
view->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
|
|
@ -178,7 +178,8 @@ public:
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
// register own handler to detect whether signal has been emitted
|
// register own handler to detect whether signal has been emitted
|
||||||
m_emittedConnection = QObject::connect(sender, signal, sender, [this] { m_signalEmitted = true; }, Qt::DirectConnection);
|
m_emittedConnection = QObject::connect(
|
||||||
|
sender, signal, sender, [this] { m_signalEmitted = true; }, Qt::DirectConnection);
|
||||||
#ifndef SYNCTHINGTESTHELPER_FOR_CLI
|
#ifndef SYNCTHINGTESTHELPER_FOR_CLI
|
||||||
if (!m_emittedConnection) {
|
if (!m_emittedConnection) {
|
||||||
CPPUNIT_FAIL(argsToString("Unable to connect signal ", signalName().data(), " to check for signal emmitation"));
|
CPPUNIT_FAIL(argsToString("Unable to connect signal ", signalName().data(), " to check for signal emmitation"));
|
||||||
|
|
Loading…
Reference in New Issue