Inital commit of the Komplex Hub
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
qt_add_library(QuickStudioUtils STATIC)
|
||||
qt6_add_qml_module(QuickStudioUtils
|
||||
URI "QtQuick.Studio.Utils"
|
||||
VERSION "${PROJECT_VERSION}"
|
||||
RESOURCE_PREFIX "/qt-project.org/imports"
|
||||
DESIGNER_SUPPORTED
|
||||
PAST_MAJOR_VERSIONS 1
|
||||
SOURCES
|
||||
quickstudiocsvtablemodel.cpp
|
||||
quickstudiocsvtablemodel.h
|
||||
quickstudiofilereader.cpp
|
||||
quickstudiofilereader.h
|
||||
QML_FILES
|
||||
JsonListModel.qml
|
||||
JsonBackend.qml
|
||||
ChildListModel.qml
|
||||
)
|
||||
|
||||
target_link_libraries(QuickStudioUtils PRIVATE Qt6::Gui)
|
||||
|
||||
register_plugin(QuickStudioUtils)
|
||||
@@ -0,0 +1,61 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2023 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Dialogs module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL3$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt 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 http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or later as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.GPL included in
|
||||
** the packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 2.0 requirements will be
|
||||
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQml.Models as M
|
||||
import QtQuick.Studio.Utils
|
||||
|
||||
M.ListModel {
|
||||
id: listModel
|
||||
|
||||
property string modelName
|
||||
property var jsonObject: null
|
||||
|
||||
dynamicRoles: true
|
||||
|
||||
// qmllint disable compiler
|
||||
|
||||
onJsonObjectChanged: {
|
||||
listModel.clear()
|
||||
var objectArray = listModel.jsonObject
|
||||
if (modelName.modelName !== "")
|
||||
objectArray = objectArray[listModel.modelName]
|
||||
for (var key in objectArray) {
|
||||
var jo = objectArray[key]
|
||||
listModel.append(jo)
|
||||
}
|
||||
}
|
||||
// qmllint enable compiler
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2023 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Dialogs module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL3$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt 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 http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or later as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.GPL included in
|
||||
** the packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 2.0 requirements will be
|
||||
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Studio.Utils
|
||||
|
||||
QtObject {
|
||||
id: server
|
||||
property url source
|
||||
|
||||
property FileReader fileReader: FileReader {
|
||||
id: fileReader
|
||||
filePath: server.source
|
||||
onContentChanged: server.updateJSON()
|
||||
}
|
||||
|
||||
// qmllint disable compiler
|
||||
function updateJSON() {
|
||||
|
||||
if (fileReader.content === "")
|
||||
return
|
||||
|
||||
var objectArray = parseJSONString(fileReader.content)
|
||||
for (var key in objectArray) {
|
||||
var jo = objectArray[key]
|
||||
if (server[key] !== undefined)
|
||||
server[key] = jo
|
||||
else
|
||||
console.warn(key, "undefined")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function parseJSONString(jsonString) {
|
||||
var objectArray = JSON.parse(jsonString)
|
||||
if (!objectArray)
|
||||
console.error("JSON parsing failed")
|
||||
|
||||
return objectArray
|
||||
}
|
||||
// qmllint enable compiler
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2023 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Dialogs module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL3$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt 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 http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or later as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.GPL included in
|
||||
** the packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 2.0 requirements will be
|
||||
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQml
|
||||
import QtQml.Models as M
|
||||
import QtQuick.Studio.Utils as U
|
||||
|
||||
M.ListModel {
|
||||
id: listModel
|
||||
|
||||
property url source
|
||||
property var jsonObject
|
||||
dynamicRoles: true
|
||||
|
||||
property U.FileReader fileReader: U.FileReader {
|
||||
id: fileReader
|
||||
filePath: listModel.source
|
||||
onContentChanged: listModel.updateJSON()
|
||||
}
|
||||
|
||||
// qmllint disable compiler
|
||||
onJsonObjectChanged: {
|
||||
listModel.clear()
|
||||
var objectArray = listModel.jsonObject
|
||||
|
||||
for (var key in objectArray) {
|
||||
var jo = objectArray[key]
|
||||
listModel.append(jo)
|
||||
}
|
||||
}
|
||||
|
||||
function updateJSON() {
|
||||
var objectArray = JSON.parse(fileReader.content)
|
||||
listModel.jsonObject = fromLocalJson(objectArray)
|
||||
invalidateChildModels()
|
||||
}
|
||||
|
||||
function isObject(obj) {
|
||||
return obj && obj.constructor === Object
|
||||
}
|
||||
|
||||
function fromLocalJson(localJson) {
|
||||
if (!isObject(localJson))
|
||||
return {}
|
||||
|
||||
var parsedModel = {}
|
||||
for (let collectionName in localJson) {
|
||||
let collection = localJson[collectionName]
|
||||
if (isObject(collection)) {
|
||||
if (Array.isArray(collection.columns) && Array.isArray(collection.data)) {
|
||||
let propertyNames = []
|
||||
let extractedCollection = []
|
||||
|
||||
for (let columnId in collection.columns) {
|
||||
let column = collection.columns[columnId]
|
||||
propertyNames.push(isObject(column) ? column.name : null)
|
||||
}
|
||||
|
||||
for (let rowId in collection.data) {
|
||||
let extractedElement = {}
|
||||
let row = collection.data[rowId]
|
||||
if (Array.isArray(row)) {
|
||||
let maxIdx = Math.min(row.length, propertyNames.length)
|
||||
for (let idx = 0; idx < maxIdx; ++idx) {
|
||||
let propertyName = propertyNames[idx]
|
||||
if (propertyName !== "") {
|
||||
let value = row[idx]
|
||||
if (value !== undefined && value !== null)
|
||||
extractedElement[propertyName] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
extractedCollection.push(extractedElement)
|
||||
}
|
||||
parsedModel[collectionName] = extractedCollection
|
||||
}
|
||||
}
|
||||
}
|
||||
return parsedModel
|
||||
}
|
||||
|
||||
function invalidateChildModels() {
|
||||
for (let property in listModel) {
|
||||
let propertyValue = listModel[property]
|
||||
let propertyValueIsObject = propertyValue && typeof(propertyValue) === "object"
|
||||
|
||||
if (propertyValueIsObject && propertyValue.jsonObject !== undefined)
|
||||
propertyValue.jsonObject = listModel.jsonObject
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
updateJSON()
|
||||
}
|
||||
|
||||
// qmllint enable compiler
|
||||
}
|
||||
@@ -0,0 +1,307 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2023 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Dialogs module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL3$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt 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 http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or later as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.GPL included in
|
||||
** the packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 2.0 requirements will be
|
||||
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "quickstudiocsvtablemodel.h"
|
||||
|
||||
#include <QColor>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QFileSystemWatcher>
|
||||
#include <QLoggingCategory>
|
||||
#include <QRegularExpression>
|
||||
#include <QTextStream>
|
||||
|
||||
static inline QColor fromString(const QString &colorName)
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)
|
||||
return QColor::fromString(colorName);
|
||||
#else
|
||||
return colorName;
|
||||
#endif // >= Qt 6.4
|
||||
}
|
||||
|
||||
static inline bool isValidColorName(const QString &colorName)
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)
|
||||
return QColor::isValidColorName(colorName);
|
||||
#else
|
||||
constexpr QStringView colorPattern(
|
||||
u"(?<color>^(?:#(?:(?:[0-9a-fA-F]{2}){3,4}|(?:[0-9a-fA-F]){3,4}))$)");
|
||||
static QRegularExpression colorRegex(colorPattern.toString());
|
||||
return colorRegex.match(colorName).hasMatch();
|
||||
#endif // >= Qt 6.4
|
||||
}
|
||||
|
||||
static QVariant stringToVariant(const QString &value)
|
||||
{
|
||||
constexpr QStringView typesPattern{u"(?<boolean>^(?:true|false)$)|"
|
||||
u"(?<number>^(?:-?(?:0|[1-9]\\d*)?(?:\\.\\d*)?(?<=\\d|\\.)"
|
||||
u"(?:e-?(?:0|[1-9]\\d*))?|0x[0-9a-f]+)$)|"
|
||||
u"(?<color>^(?:#(?:(?:[0-9a-fA-F]{2}){3,4}|"
|
||||
u"(?:[0-9a-fA-F]){3,4}))$)"};
|
||||
|
||||
static QRegularExpression validator(typesPattern.toString());
|
||||
const QString trimmedValue = value.trimmed();
|
||||
QRegularExpressionMatch match = validator.match(trimmedValue);
|
||||
|
||||
if (!match.hasMatch())
|
||||
return value;
|
||||
|
||||
if (!match.captured(u"boolean").isEmpty())
|
||||
return QVariant::fromValue<bool>(trimmedValue.at(0).toLower() == u't');
|
||||
|
||||
if (!match.captured(u"number").isEmpty())
|
||||
return trimmedValue.toDouble();
|
||||
|
||||
if (!match.captured(u"color").isEmpty())
|
||||
return ::fromString(trimmedValue);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static QVariant stringToVariant(const QString &value, QMetaType::Type type, bool *ok = nullptr)
|
||||
{
|
||||
if (type == QMetaType::Bool) {
|
||||
const QString lowerValue = value.toLower().trimmed();
|
||||
bool conversionOk = true;
|
||||
bool booleanValue = false;
|
||||
|
||||
if (lowerValue == u"true")
|
||||
booleanValue = true;
|
||||
else if (lowerValue == u"false")
|
||||
booleanValue = false;
|
||||
else
|
||||
conversionOk = false;
|
||||
|
||||
if (ok)
|
||||
*ok = conversionOk;
|
||||
|
||||
if (conversionOk)
|
||||
return booleanValue;
|
||||
}
|
||||
|
||||
if (type == QMetaType::Double) {
|
||||
bool conversionOk = false;
|
||||
double numericValue = value.toDouble(&conversionOk);
|
||||
if (ok)
|
||||
*ok = conversionOk;
|
||||
|
||||
if (conversionOk)
|
||||
return numericValue;
|
||||
}
|
||||
|
||||
if (type == QMetaType::QColor) {
|
||||
bool conversionOk = ::isValidColorName(value);
|
||||
if (ok)
|
||||
*ok = conversionOk;
|
||||
|
||||
if (conversionOk)
|
||||
return ::fromString(value);
|
||||
}
|
||||
|
||||
if (type == QMetaType::QString) {
|
||||
if (ok)
|
||||
*ok = !value.isEmpty();
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static QString urlToLocalPath(const QUrl &url)
|
||||
{
|
||||
QString localPath;
|
||||
|
||||
if (url.isLocalFile())
|
||||
localPath = url.toLocalFile();
|
||||
|
||||
if (url.scheme() == QLatin1String("qrc")) {
|
||||
const QString &path = url.path();
|
||||
localPath = QStringLiteral(":") + path;
|
||||
}
|
||||
|
||||
return localPath;
|
||||
}
|
||||
|
||||
#ifndef Q_STATIC_LOGGING_CATEGORY // introduced with Qt 6.9
|
||||
static Q_LOGGING_CATEGORY(quickStudioCsvTableModelDebug, "qt.StudioCsvTableModel.debug", QtDebugMsg)
|
||||
#else
|
||||
Q_STATIC_LOGGING_CATEGORY(quickStudioCsvTableModelDebug, "qt.StudioCsvTableModel.debug", QtDebugMsg)
|
||||
#endif
|
||||
|
||||
|
||||
QuickStudioCsvTableModel::QuickStudioCsvTableModel(QObject *parent)
|
||||
: QAbstractTableModel(parent)
|
||||
, m_fileWatcher(new QFileSystemWatcher(this))
|
||||
{
|
||||
connect(m_fileWatcher,
|
||||
&QFileSystemWatcher::fileChanged,
|
||||
this,
|
||||
&QuickStudioCsvTableModel::checkPathAndReload);
|
||||
}
|
||||
|
||||
int QuickStudioCsvTableModel::rowCount([[maybe_unused]] const QModelIndex &parent) const
|
||||
{
|
||||
return m_rows.size();
|
||||
}
|
||||
|
||||
int QuickStudioCsvTableModel::columnCount([[maybe_unused]] const QModelIndex &parent) const
|
||||
{
|
||||
return m_headers.size();
|
||||
}
|
||||
|
||||
QVariant QuickStudioCsvTableModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return {};
|
||||
|
||||
const QHash<int, QVariant> &recordData = m_rows.at(index.row());
|
||||
|
||||
if (role == Qt::DisplayRole)
|
||||
return recordData.value(index.column()).toString();
|
||||
|
||||
return recordData.value(index.column());
|
||||
}
|
||||
|
||||
QVariant QuickStudioCsvTableModel::headerData(int section,
|
||||
Qt::Orientation orientation,
|
||||
[[maybe_unused]] int role) const
|
||||
{
|
||||
if (orientation == Qt::Horizontal) {
|
||||
if (section > -1 && section < m_headers.size())
|
||||
return m_headers.at(section);
|
||||
} else if (orientation == Qt::Vertical) {
|
||||
if (section > -1 && section < m_rows.size())
|
||||
return section;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
QUrl QuickStudioCsvTableModel::source() const
|
||||
{
|
||||
return m_source;
|
||||
}
|
||||
|
||||
void QuickStudioCsvTableModel::setSource(const QUrl &newSource)
|
||||
{
|
||||
if (m_source == newSource)
|
||||
return;
|
||||
|
||||
m_source = newSource;
|
||||
emit this->sourceChanged(m_source);
|
||||
|
||||
startWatchingSource();
|
||||
reloadModel();
|
||||
}
|
||||
|
||||
void QuickStudioCsvTableModel::reloadModel()
|
||||
{
|
||||
beginResetModel();
|
||||
m_headers.clear();
|
||||
m_rows.clear();
|
||||
m_types.clear();
|
||||
m_columnIsClean.clear();
|
||||
|
||||
QString filePath = ::urlToLocalPath(source());
|
||||
QFile sourceFile(filePath);
|
||||
|
||||
if (!sourceFile.open(QFile::ReadOnly)) {
|
||||
qWarning() << "File cannot be opened:" << sourceFile.errorString();
|
||||
endResetModel();
|
||||
return;
|
||||
}
|
||||
|
||||
QTextStream stream(&sourceFile);
|
||||
|
||||
if (!stream.atEnd())
|
||||
m_headers = stream.readLine().split(u',', Qt::KeepEmptyParts);
|
||||
|
||||
m_types.insert(0, m_headers.size(), QMetaType::UnknownType);
|
||||
m_columnIsClean.insert(0, m_headers.size(), true);
|
||||
|
||||
if (!m_headers.isEmpty()) {
|
||||
while (!stream.atEnd()) {
|
||||
const QStringList recordDataList = stream.readLine().split(u',', Qt::KeepEmptyParts);
|
||||
int column = -1;
|
||||
QHash<int, QVariant> recordData;
|
||||
for (const QString &cellString : recordDataList) {
|
||||
if (++column == m_headers.size())
|
||||
break;
|
||||
|
||||
if (!cellString.size())
|
||||
continue;
|
||||
|
||||
const QMetaType::Type &type = m_types.at(column);
|
||||
|
||||
QVariant cellData;
|
||||
if (type == QMetaType::UnknownType) {
|
||||
cellData = stringToVariant(cellString);
|
||||
m_types.replace(column, QMetaType::Type(cellData.typeId()));
|
||||
} else {
|
||||
bool columnIsClean = m_columnIsClean.at(column);
|
||||
bool *ok = columnIsClean ? &columnIsClean : nullptr;
|
||||
cellData = stringToVariant(cellString, type, ok);
|
||||
if (ok)
|
||||
m_columnIsClean.replace(column, *ok);
|
||||
}
|
||||
recordData.insert(column, cellData);
|
||||
}
|
||||
m_rows.append(recordData);
|
||||
}
|
||||
}
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void QuickStudioCsvTableModel::checkPathAndReload(const QString &path)
|
||||
{
|
||||
QString sourceLocalPath = ::urlToLocalPath(source());
|
||||
if (path == sourceLocalPath)
|
||||
reloadModel();
|
||||
}
|
||||
|
||||
void QuickStudioCsvTableModel::startWatchingSource()
|
||||
{
|
||||
qCDebug(quickStudioCsvTableModelDebug) << Q_FUNC_INFO << "Load file: " << source();
|
||||
|
||||
const QStringList oldWatchingFiles = m_fileWatcher->files();
|
||||
if (oldWatchingFiles.size())
|
||||
m_fileWatcher->removePaths(oldWatchingFiles);
|
||||
|
||||
QString localPath = ::urlToLocalPath(source());
|
||||
if (QFileInfo(localPath).isFile())
|
||||
m_fileWatcher->addPath(localPath);
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2023 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Dialogs module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL3$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt 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 http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or later as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.GPL included in
|
||||
** the packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 2.0 requirements will be
|
||||
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QUICKSTUDIOCSVTABLEMODEL_P_H
|
||||
#define QUICKSTUDIOCSVTABLEMODEL_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QtCore/qurl.h>
|
||||
#include <QtQml/qqml.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QFileSystemWatcher;
|
||||
class QuickStudioCsvTableModel : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
QML_NAMED_ELEMENT(CsvTableModel)
|
||||
QML_ADDED_IN_VERSION(6, 2)
|
||||
|
||||
Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
|
||||
|
||||
public:
|
||||
explicit QuickStudioCsvTableModel(QObject *parent = nullptr);
|
||||
|
||||
int rowCount(const QModelIndex &parent = {}) const override;
|
||||
int columnCount(const QModelIndex &parent = {}) const override;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
QVariant headerData(int section,
|
||||
Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const override;
|
||||
|
||||
QUrl source() const;
|
||||
void setSource(const QUrl &newSource);
|
||||
|
||||
signals:
|
||||
void sourceChanged(const QUrl &url);
|
||||
|
||||
private slots:
|
||||
void reloadModel();
|
||||
void checkPathAndReload(const QString &path);
|
||||
|
||||
private:
|
||||
void startWatchingSource();
|
||||
|
||||
QFileSystemWatcher *m_fileWatcher = nullptr;
|
||||
QUrl m_source;
|
||||
|
||||
QStringList m_headers;
|
||||
QList<QHash<int, QVariant>> m_rows;
|
||||
QList<QMetaType::Type> m_types;
|
||||
QList<bool> m_columnIsClean;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QML_DECLARE_TYPE(QuickStudioCsvTableModel)
|
||||
|
||||
#endif // QUICKSTUDIOCSVTABLEMODEL_P_H
|
||||
@@ -0,0 +1,112 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2023 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Dialogs module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL3$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt 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 http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or later as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.GPL included in
|
||||
** the packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 2.0 requirements will be
|
||||
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "quickstudiofilereader.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QDirIterator>
|
||||
#include <QFileSystemWatcher>
|
||||
#include <QLoggingCategory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#ifndef Q_STATIC_LOGGING_CATEGORY // introduced with Qt 6.9
|
||||
static Q_LOGGING_CATEGORY(quickStudioFileReaderDebug, "qt.Studioapplication.debug", QtDebugMsg)
|
||||
#else
|
||||
Q_STATIC_LOGGING_CATEGORY(quickStudioFileReaderDebug, "qt.Studiofilereader.debug", QtDebugMsg)
|
||||
#endif
|
||||
|
||||
QuickStudioFileReader::QuickStudioFileReader(QObject *parent)
|
||||
: QObject(parent)
|
||||
{}
|
||||
|
||||
QString QuickStudioFileReader::loadFile(const QString &path)
|
||||
{
|
||||
qCDebug(quickStudioFileReaderDebug) << Q_FUNC_INFO << "Load file: " << path;
|
||||
|
||||
QFile file(path);
|
||||
bool ok = file.open(QIODevice::ReadOnly);
|
||||
|
||||
if (!ok) {
|
||||
qWarning() << "File cannot be opened:" << file.errorString();
|
||||
return {};
|
||||
}
|
||||
|
||||
if (m_watcher)
|
||||
m_watcher->deleteLater();
|
||||
|
||||
m_watcher = new QFileSystemWatcher({path}, this);
|
||||
|
||||
connect(m_watcher, &QFileSystemWatcher::fileChanged, this, &QuickStudioFileReader::reload);
|
||||
|
||||
return QString::fromUtf8(file.readAll());
|
||||
}
|
||||
|
||||
void QuickStudioFileReader::reload()
|
||||
{
|
||||
qCDebug(quickStudioFileReaderDebug) << Q_FUNC_INFO << "Load file: " << m_filePath;
|
||||
|
||||
QString localPath;
|
||||
|
||||
if (m_filePath.isLocalFile())
|
||||
localPath = m_filePath.toLocalFile();
|
||||
|
||||
if (m_filePath.scheme() == QStringLiteral("qrc")) {
|
||||
const QString &path = m_filePath.path();
|
||||
localPath = QStringLiteral(":") + path;
|
||||
}
|
||||
|
||||
QString newContent = loadFile(localPath);
|
||||
|
||||
if (newContent != m_content) {
|
||||
m_content = newContent;
|
||||
emit contentChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void QuickStudioFileReader::setFilePath(const QUrl &url)
|
||||
{
|
||||
if (url == filePath())
|
||||
return;
|
||||
|
||||
m_filePath = url;
|
||||
|
||||
reload();
|
||||
|
||||
emit filePathChanged();
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
@@ -0,0 +1,93 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2023 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Dialogs module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL3$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt 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 http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or later as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.GPL included in
|
||||
** the packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 2.0 requirements will be
|
||||
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QUICKSTUDIOUTILS_P_H
|
||||
#define QUICKSTUDIOUTILS_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtCore/qurl.h>
|
||||
#include <QtQml/qqml.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QFileSystemWatcher;
|
||||
|
||||
class QuickStudioFileReader : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
QML_NAMED_ELEMENT(FileReader)
|
||||
QML_ADDED_IN_VERSION(6, 2)
|
||||
|
||||
Q_PROPERTY(QUrl filePath READ filePath WRITE setFilePath NOTIFY filePathChanged)
|
||||
Q_PROPERTY(QString content READ content NOTIFY contentChanged)
|
||||
|
||||
public:
|
||||
explicit QuickStudioFileReader(QObject *parent = nullptr);
|
||||
|
||||
const QUrl filePath() { return m_filePath; }
|
||||
void setFilePath(const QUrl &file);
|
||||
|
||||
const QString content() { return m_content; }
|
||||
|
||||
signals:
|
||||
void filePathChanged();
|
||||
void contentChanged();
|
||||
|
||||
private:
|
||||
QString loadFile(const QString &path);
|
||||
void reload();
|
||||
|
||||
QUrl m_filePath;
|
||||
QString m_content;
|
||||
QFileSystemWatcher *m_watcher = nullptr;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QML_DECLARE_TYPE(QuickStudioFileReader)
|
||||
|
||||
#endif // QUICKSTUDIOUTILS_P_H
|
||||
Reference in New Issue
Block a user