Add support for multiple directories

This commit is contained in:
woblight
2019-12-01 21:44:14 +01:00
parent 3009f63127
commit 26cc43e37c
7 changed files with 268 additions and 196 deletions
+12 -8
View File
@@ -41,13 +41,6 @@ Page {
ToolTip.text: "Upgrade all addons"
Material.foreground: Material.background
}
ToolButton {
hoverEnabled: true
action: openAddonsFolder
ToolTip.visible: hovered
ToolTip.text: "Open addons folder externally"
Material.foreground: Material.background
}
Item {
Layout.fillWidth: true
@@ -75,8 +68,19 @@ Page {
model: Engine.addons
id: listView
section.property: "modelData.path"
section.criteria: ViewSection.FullString
section.delegate:
Button {
text: section
icon.name: "go-parent-folder"
width: Math.min(listView.width, implicitWidth)
onClicked: Qt.openUrlExternally((Qt.platform.os == "windows" ? "file:///" : "file://")+section)
display: AbstractButton.TextBesideIcon
}
delegate: MouseArea {
property Addon addon: Engine.addons[index]
property Addon addon: Engine.addons[index]
width: parent.width
implicitHeight: row.height
hoverEnabled: true
+140 -128
View File
@@ -22,142 +22,154 @@ import QtQuick.Controls.Material 2.2
import QtQuick.Controls.Universal 2.2
import Qt.labs.settings 1.0
ColumnLayout {
RowLayout {
Layout.fillWidth: true
TextField {
Layout.fillWidth: true
id: path
text: Engine.addonsPath
onAccepted: Engine.addonsPath = text
placeholderText: qsTr("Path to AddOns folder")
hoverEnabled: true
ToolTip.visible: hovered
ToolTip.text: qsTr("Path to the folder containing the addons")
enabled: Control.status == Control.Ready && addonsReady
Pane {
ColumnLayout {
width: parent.width
Repeater {
model: Engine.addonsPaths.length
RowLayout {
Layout.fillWidth: true
TextField {
Layout.fillWidth: true
id: path
text: Engine.addonsPaths[index]
onAccepted: Engine.addonsPath = text
placeholderText: qsTr("Path to AddOns folder")
hoverEnabled: true
ToolTip.visible: hovered
ToolTip.text: qsTr("Path to the folder containing the addons")
enabled: Control.status == Control.Ready && addonsReady
}
Button {
enabled: Control.status == Control.Ready && addonsReady
text: qsTr("Browse")
onClicked: {fileDialog.selector = index; fileDialog.folder = "file://" + Engine.addonsPaths[index]; fileDialog.visible = true}
hoverEnabled: true
ToolTip.visible: hovered
ToolTip.text: qsTr("Choose the folder containing the addons")
}
}
}
Button {
enabled: Control.status == Control.Ready && addonsReady
text: qsTr("Browse")
onClicked: fileDialog.visible = true
hoverEnabled: true
ToolTip.visible: hovered
ToolTip.text: qsTr("Choose the folder containing the addons")
text: qsTr("Add directory")
Layout.alignment: Qt.AlignRight
onClicked: {fileDialog.selector = -1; fileDialog.visible = true}
}
}
CheckBox {
Layout.fillWidth: true
tristate: Engine.minimizeToTray == Engine.MinimizeToTrayAsk
onCheckedChanged: Engine.minimizeToTray = checked ? Engine.MinimizeToTrayYes : Engine.MinimizeToTrayNo
checkState: Engine.minimizeToTray == Engine.MinimizeToTrayAsk ?
Qt.PartiallyChecked :
Engine.minimizeToTray == Engine.MinimizeToTrayYes ?
Qt.Checked : Qt.Unchecked
text: qsTr("Minimize to System Tray")
hoverEnabled: true
ToolTip.visible: hovered
ToolTip.text: qsTr("Minimize to System Tray when the main window is closed.")
}
GroupBox {
Layout.fillWidth: true
title: qsTr("Style")
Flow {
anchors.fill: parent
spacing: 4
ComboBox {
model: Engine.availableStyles
currentIndex: Engine.availableStyles.indexOf(Engine.style)
onActivated: {
Engine.style = Engine.availableStyles[currentIndex]
restartDialog.visible = true
}
ToolTip.text: qsTr("Requires restart")
ToolTip.visible: hovered
CheckBox {
Layout.fillWidth: true
tristate: Engine.minimizeToTray == Engine.MinimizeToTrayAsk
onCheckedChanged: Engine.minimizeToTray = checked ? Engine.MinimizeToTrayYes : Engine.MinimizeToTrayNo
checkState: Engine.minimizeToTray == Engine.MinimizeToTrayAsk ?
Qt.PartiallyChecked :
Engine.minimizeToTray == Engine.MinimizeToTrayYes ?
Qt.Checked : Qt.Unchecked
text: qsTr("Minimize to System Tray")
hoverEnabled: true
}
ComboBox {
id: materialTheme
visible: Engine.style == "Material"
model: ["Light", "Dark"]
onCurrentIndexChanged: window.Material.theme = currentIndex
}
ComboBox {
id: universalTheme
visible: Engine.style == "Universal"
model: ["Light", "Dark", "System"]
onActivated: window.Universal.theme = currentIndex
}
ListModel {
id: materialColors
dynamicRoles: true
Component.onCompleted: {
for (var i = 0; i < 19; i++)
append({"color": Material.color(i)})}
}
ListModel {
id: materialDarkColors
dynamicRoles: true
Component.onCompleted: {
for (var i = 0; i < 19; i++)
append({"color": Material.color(i,Material.Shade200)})}
}
ListModel {
id: universalColors
dynamicRoles: true
Component.onCompleted: {
for (var i = 0; i < 20; i++)
append({"color": Universal.color(i)})}
}
ToolTip.visible: hovered
ToolTip.text: qsTr("Minimize to System Tray when the main window is closed.")
}
GroupBox {
Layout.fillWidth: true
title: qsTr("Style")
Flow {
anchors.fill: parent
spacing: 4
ComboBox {
model: Engine.availableStyles
currentIndex: Engine.availableStyles.indexOf(Engine.style)
onActivated: {
Engine.style = Engine.availableStyles[currentIndex]
restartDialog.visible = true
}
ToolTip.text: qsTr("Requires restart")
ToolTip.visible: hovered
hoverEnabled: true
}
ComboBox {
id: materialTheme
visible: Engine.style == "Material"
model: ["Light", "Dark"]
onCurrentIndexChanged: window.Material.theme = currentIndex
}
ComboBox {
id: universalTheme
visible: Engine.style == "Universal"
model: ["Light", "Dark", "System"]
onActivated: window.Universal.theme = currentIndex
}
ListModel {
id: materialColors
dynamicRoles: true
Component.onCompleted: {
for (var i = 0; i < 19; i++)
append({"color": Material.color(i)})}
}
ListModel {
id: materialDarkColors
dynamicRoles: true
Component.onCompleted: {
for (var i = 0; i < 19; i++)
append({"color": Material.color(i,Material.Shade200)})}
}
ListModel {
id: universalColors
dynamicRoles: true
Component.onCompleted: {
for (var i = 0; i < 20; i++)
append({"color": Universal.color(i)})}
}
ColorPicker {
id: materialPrimary
visible: Engine.style == "Material"
text: qsTr("Primary:")
model: materialTheme.currentIndex === Material.Dark ? materialDarkColors : materialColors
currentIndex: Material.Indigo
onColorChanged: window.Material.primary = color
}
ColorPicker {
id: materialAccent
visible: Engine.style == "Material"
text: qsTr("Accent:")
model: materialTheme.currentIndex === Material.Dark ? materialDarkColors : materialColors
currentIndex: Material.Pink
onColorChanged: window.Material.accent = color
}
ColorPicker {
id: universalAccent
visible: Engine.style == "Universal"
text: qsTr("Accent:")
model: universalColors
currentIndex: Universal.Cobalt
onColorChanged: window.Universal.accent = color
}
ColorPicker {
id: materialPrimary
visible: Engine.style == "Material"
text: qsTr("Primary:")
model: materialTheme.currentIndex === Material.Dark ? materialDarkColors : materialColors
currentIndex: Material.Indigo
onColorChanged: window.Material.primary = color
}
ColorPicker {
id: materialAccent
visible: Engine.style == "Material"
text: qsTr("Accent:")
model: materialTheme.currentIndex === Material.Dark ? materialDarkColors : materialColors
currentIndex: Material.Pink
onColorChanged: window.Material.accent = color
}
ColorPicker {
id: universalAccent
visible: Engine.style == "Universal"
text: qsTr("Accent:")
model: universalColors
currentIndex: Universal.Cobalt
onColorChanged: window.Universal.accent = color
}
Settings {
category: "Material"
property alias primary: materialPrimary.currentIndex
property alias accent: materialAccent.currentIndex
property alias theme: materialTheme.currentIndex
}
Settings {
category: "Universal"
property alias accent: universalAccent.currentIndex
property alias theme: universalTheme.currentIndex
Settings {
category: "Material"
property alias primary: materialPrimary.currentIndex
property alias accent: materialAccent.currentIndex
property alias theme: materialTheme.currentIndex
}
Settings {
category: "Universal"
property alias accent: universalAccent.currentIndex
property alias theme: universalTheme.currentIndex
}
}
}
}
Dialog {
id: restartDialog
parent: overlay
x: (parent.width - width) / 2
y: (parent.height - height) / 2
standardButtons: Dialog.Yes | Dialog.No
Label {
anchors.fill: parent
text: qsTr("The application must be restarted for this change to take effect.\nRestart now?")
wrapMode: Text.WordWrap
Dialog {
id: restartDialog
parent: overlay
x: (parent.width - width) / 2
y: (parent.height - height) / 2
standardButtons: Dialog.Yes | Dialog.No
Label {
anchors.fill: parent
text: qsTr("The application must be restarted for this change to take effect.\nRestart now?")
wrapMode: Text.WordWrap
}
onAccepted: Qt.exit(1)
}
onAccepted: Qt.exit(1)
}
}
+15 -10
View File
@@ -28,8 +28,8 @@
#include <QFutureWatcher>
#include <QReadWriteLock>
Addon::Addon(QString name, git_repository *repo, QObject *parent) : QObject(parent),
m_name(name), m_repo(repo, &git_repository_free), m_progress(0), m_total(0), m_status(Status::Ready), m_gitStatus(GitStatusFlag::UpToDate), m_pool(new QThreadPool(this))
Addon::Addon(QString name, git_repository *repo, QString path, QObject *parent) : QObject(parent),
m_name(name), m_repo(repo, &git_repository_free), m_progress(0), m_total(0), m_status(Status::Ready), m_gitStatus(GitStatusFlag::UpToDate), m_pool(new QThreadPool(this)), m_path(path)
{
connect(this, &Addon::remoteChanged, this, &Addon::fetchRemote);
connect(this, &Addon::currentBranchChanged, this, &Addon::updateGitStatus);
@@ -337,7 +337,7 @@ void Addon::uninstall()
removeSubfolders();
closeRepo();
delegate("Removing addon folder", [this](){
removeFolder(Control::instance()->addonsPath() + "/" + m_name);
removeFolder(m_path + "/" + m_name);
}, [](){Control::instance()->scanForAddons();});
}
@@ -404,7 +404,7 @@ void Addon::removeSubfolders()
{
delegate("Removing Subfolders", [this](){
QStringList paths(m_subfolders);
std::transform(paths.begin(), paths.end(), paths.begin(), [](auto p){return Control::instance()->addonsPath() + "/" + p;});
std::transform(paths.begin(), paths.end(), paths.begin(), [this](auto p){return m_path + "/" + p;});
removeFolders(paths);
});
}
@@ -412,7 +412,7 @@ void Addon::removeSubfolders()
void Addon::unpackSubfolders(){
delegate("Unpacking Subfolders", [this](){
QStringList errors;
QDir addonsDir(Control::instance()->addonsPath());
QDir addonsDir(m_path);
if (m_subfolders.contains(m_name, Qt::CaseInsensitive)) {
closeRepo();
QString oldName = m_name;
@@ -513,9 +513,9 @@ void Addon::reclone()
check_git_return(git_branch_name(&remote, remoteRefForBranch(m_currentBranch)));
QString oldRemote(remote);
closeRepo();
if (removeFolder(Control::instance()->addonsPath() + "/" + name() + "/.git")){
if (removeFolder(m_path + "/" + name() + "/.git")){
git_repository *repo = nullptr;
check_git_return(git_repository_init(&repo, (Control::instance()->addonsPath() + "/" + m_name).toLocal8Bit(), false));
check_git_return(git_repository_init(&repo, (m_path + "/" + m_name).toLocal8Bit(), false));
m_repo.reset(repo);
for (size_t i = 0; i < remotes.count; i++) {
AutoPtr remote(&git_remote_free);
@@ -542,9 +542,9 @@ void Addon::reclone()
void Addon::loadReadme()
{
delegate("Readme Loading",[this](){
QFileInfo md(Control::instance()->addonsPath() + "/" + m_name + "/README.md");
QFileInfo md(m_path + "/" + m_name + "/README.md");
if (!md.exists() && !md.isFile()) {
QDir repodir(Control::instance()->addonsPath() + "/" + m_name);
QDir repodir(m_path + "/" + m_name);
auto a = repodir.entryInfoList({"readme*"});
if (a.size() > 0)
md = a[0];
@@ -624,6 +624,11 @@ QString Addon::readme() const
return m_readme;
}
QString Addon::path() const
{
return m_path;
}
void Addon::closeRepo()
{
m_repo.reset();
@@ -632,7 +637,7 @@ void Addon::closeRepo()
void Addon::openRepo()
{
git_repository *repo = nullptr;
git_repository_open(&repo, (Control::instance()->addonsPath() + "/" + m_name).toLocal8Bit());
git_repository_open(&repo, (m_path + "/" + m_name).toLocal8Bit());
m_repo.reset(repo);
}
+8 -1
View File
@@ -53,6 +53,8 @@ class Addon : public QObject
int m_total;
QString m_path;
QMutex m_mutex;
QWaitCondition m_wait;
void *m_result;
@@ -67,6 +69,7 @@ public:
Q_PROPERTY(QStringList subfolders READ subfolders WRITE setSubfolders NOTIFY subfoldersChanged)
Q_PROPERTY(QString filesToRemove READ filesToRemove WRITE setFilesToRemove NOTIFY filesToRemoveChanged)
Q_PROPERTY(QString readme READ readme WRITE setReadme NOTIFY readmeChanged)
Q_PROPERTY(QString path READ path)
enum class Status {
Error = -1,
@@ -92,7 +95,7 @@ public:
Q_PROPERTY(GitStatus gitStatus READ gitStatus WRITE setGitStatus NOTIFY gitStatusChanged)
Q_FLAGS(GitStatus)
explicit Addon(QString name, git_repository *repo, QObject *parent = nullptr);
explicit Addon(QString name, git_repository *repo, QString path, QObject *parent = nullptr);
QString name() const;
@@ -118,6 +121,8 @@ public:
QString readme() const;
QString path() const;
private:
Status m_status;
@@ -169,6 +174,8 @@ signals:
void readmeChanged(QString readme);
void pathChanged(QString path);
public slots:
void setName(QString name);
void update();
+75 -29
View File
@@ -41,19 +41,31 @@ Control::Control(QObject *parent) : QObject(parent),
m_style(QQuickStyle::name()),m_availableStyles(QQuickStyle::availableStyles())
{
connect(this, &Control::addonsPathChanged, this, &Control::scanForAddons);
connect(this, &Control::addonsPathChanged, this, &Control::saveAddonsPath);
connect(this, &Control::addonsPathsChanged, this, &Control::saveAddonsPaths);
}
void Control::init() {
git_libgit2_init();
QSettings settings;
setAddonsPath(settings.value("addonsPath").toString());
if (settings.value("addonsPaths").isNull()) {
setAddonsPath(-1, settings.value("addonsPath").toString());
settings.remove("addonsPath");
} else {
auto paths = settings.value("addonsPaths").toStringList();
for (int i = 0; i < paths.length(); i++)
setAddonsPath(-1, paths[i]);
}
setFirstBoot(settings.value("firstBoot",true).toBool());
setMinimizeToTray((MinimizeToTray)settings.value("minimizeToTray",(int)MinimizeToTrayAsk).toInt());
nam = new QNetworkAccessManager(this);
checkForUpdates();
}
QStringList Control::addonsPaths() const
{
return m_addonsPaths;
}
void Control::delegate(QString taskname, auto work, auto callback)
{
Q_ASSERT_X(QThread::currentThread() == thread(), "delegate", "Attempt to delegate from another thread.");
@@ -108,11 +120,6 @@ QList<QObject *> Control::addons() const
return m_addons;
}
QString Control::addonsPath() const
{
return m_addonsPath;
}
Control *Control::instance()
{
if (!m_instance)
@@ -265,28 +272,61 @@ void Control::setAddons(QList<QObject *> addons)
emit addonsChanged(m_addons);
}
void Control::setAddonsPath(QString addonsPath)
void Control::setAddonsPath(int index, QString addonsPath)
{
addonsPath = QUrl::fromLocalFile(addonsPath).adjusted(QUrl::NormalizePathSegments|QUrl::StripTrailingSlash).toLocalFile();
if (m_addonsPath == addonsPath)
if (addonsPath.isNull()) {
for (int i = 0; i < m_addons.size();) {
int s = m_addons.size();
if (static_cast<Addon*>(m_addons[i])->path() == m_addonsPaths[index])
delete m_addons.takeAt(i);
if (s != m_addons.size())
emit addonsChanged(m_addons);
else i++;
}
m_addonsPaths.removeAt(index);
emit addonsPathsChanged(m_addonsPaths);
return;
}
addonsPath = QUrl::fromLocalFile(addonsPath).adjusted(QUrl::NormalizePathSegments|QUrl::StripTrailingSlash).toLocalFile();
if (index == -1) {
m_addonsPaths.append(addonsPath);
index = m_addonsPaths.size() -1;
} else {
if (m_addonsPaths[index] == addonsPath)
return;
for (int i = 0; i < m_addons.size();) {
if (static_cast<Addon*>(m_addons[i])->path() == m_addonsPaths[index])
delete m_addons.takeAt(i);
else i++;
}
m_addonsPaths[index] = addonsPath;
}
m_addonsPath = addonsPath;
emit addonsPathChanged(m_addonsPath);
emit addonsPathChanged(index, m_addonsPaths[index]);
emit addonsPathsChanged(m_addonsPaths);
}
void Control::saveAddonsPath()
void Control::saveAddonsPaths()
{
QSettings settings;
settings.setValue("addonsPath", m_addonsPath);
settings.setValue("addonsPaths", m_addonsPaths);
}
void Control::scanForAddons()
void Control::scanForAddons(int i)
{
if (i == -1) {
foreach (QObject *addon, m_addons)
addon->deleteLater();
QObjectList ol;
setAddons(ol);
for (int k = 0; k < m_addonsPaths.size(); ++k)
scanForAddons(k);
return;
}
using init_t = QPair<QString, git_repository*>;
delegate("Scanning addons folder...", [this](){
delegate("Scanning addons folder...", [this, i](){
QList<init_t> list;
QDir addonsFolder(m_addonsPath);
QDir addonsFolder(m_addonsPaths[i]);
foreach (QFileInfo dirInfo, addonsFolder.entryInfoList(QDir::AllDirs)) {
QDir gitdir(dirInfo.canonicalFilePath() + "/.git");
if (!gitdir.exists()) continue;
@@ -299,13 +339,10 @@ void Control::scanForAddons()
list << init_t(dirInfo.fileName(), repo);
}
return list;
}, [this](auto list){
QObjectList ol;
}, [this, k=i](auto list){
foreach (init_t i, list)
ol << new Addon(i.first, i.second);
foreach (QObject *addon, m_addons)
addon->deleteLater();
setAddons(ol);
m_addons << new Addon(i.first, i.second, m_addonsPaths[k]);
emit addonsChanged(m_addons);
});
}
@@ -316,9 +353,9 @@ int clone_progress_cb(const git_transfer_progress *stats, void *payload) {
return 0;
}
void Control::clone(QUrl url)
void Control::clone(QUrl url, int i)
{
delegate("Cloning addon...",[this, url]() {
delegate("Cloning addon...",[this, url, i]() {
struct {
QString name;
git_repository *repo = nullptr;
@@ -327,14 +364,14 @@ void Control::clone(QUrl url)
data.name = url.fileName().section('.',0,0);
git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
opts.fetch_opts.callbacks.transfer_progress = &clone_progress_cb;
int error = git_clone(&data.repo, url.toString().toLocal8Bit(), (m_addonsPath + "/" + data.name).toLocal8Bit(), &opts);
int error = git_clone(&data.repo, url.toString().toLocal8Bit(), (m_addonsPaths[i] + "/" + data.name).toLocal8Bit(), &opts);
if (error < 0) {
const git_error *e = giterr_last();
data.error = QString::asprintf("Error %d/%d: %s", error, e->klass, e->message);
return data;
}
QDir dir(m_addonsPath);
QDir dir(m_addonsPaths[i]);
dir.cd(data.name);
QStringList toc = dir.entryList({"*.toc"});
if (toc.isEmpty()) {
@@ -348,9 +385,9 @@ void Control::clone(QUrl url)
git_repository_open(&data.repo, dir.canonicalPath().toLocal8Bit());
}
return data;
},[this](auto ret){
},[this, i](auto ret){
if (ret.error.isEmpty()) {
auto add = new Addon(ret.name, ret.repo);
auto add = new Addon(ret.name, ret.repo, m_addonsPaths[i]);
m_addons.prepend(add);
addonsChanged(m_addons);
add->unpackSubfolders();
@@ -536,6 +573,15 @@ void Control::setUpdateStatus(Control::UpdateStatus updateStatus)
emit updateStatusChanged(m_updateStatus);
}
void Control::setAddonsPaths(QStringList addonsPaths)
{
if (m_addonsPaths == addonsPaths)
return;
m_addonsPaths = addonsPaths;
emit addonsPathsChanged(m_addonsPaths);
}
GitException::GitException(int code) : m_code(code)
{
const git_error *e = giterr_last();
+14 -11
View File
@@ -52,17 +52,15 @@ class Control : public QObject
QList<QObject *> m_addons;
QString m_addonsPath;
public:
Q_PROPERTY(QList<QObject *> addons READ addons WRITE setAddons NOTIFY addonsChanged)
Q_PROPERTY(QString addonsPath READ addonsPath WRITE setAddonsPath NOTIFY addonsPathChanged)
Q_PROPERTY(int progress READ progress WRITE setProgress NOTIFY progressChanged)
Q_PROPERTY(int total READ total WRITE setTotal NOTIFY totalChanged)
Q_PROPERTY(QString statusMessage READ statusMessage WRITE setStatusMessage NOTIFY statusMessageChanged)
Q_PROPERTY(bool firstBoot READ firstBoot WRITE setFirstBoot NOTIFY firstBootChanged)
Q_PROPERTY(QString style READ style WRITE setStyle NOTIFY styleChanged)
Q_PROPERTY(QStringList availableStyles READ availableStyles WRITE setAvailableStyles NOTIFY availableStylesChanged)
Q_PROPERTY(QStringList addonsPaths READ addonsPaths WRITE setAddonsPaths NOTIFY addonsPathsChanged)
~Control();
@@ -95,8 +93,6 @@ public:
Q_PROPERTY(UpdateStatus updateStatus READ updateStatus WRITE setUpdateStatus NOTIFY updateStatusChanged)
QList<QObject *> addons() const;
QString addonsPath() const;
static Control *instance();
int progress() const;
@@ -121,6 +117,8 @@ public:
void init();
QStringList addonsPaths() const;
private:
static Control *m_instance;
explicit Control(QObject *parent = nullptr);
@@ -148,11 +146,11 @@ private:
UpdateStatus m_updateStatus = UpdateStatus::NoUpdate;
QStringList m_addonsPaths;
signals:
void addonsChanged(QList<QObject *> addons);
void addonsPathChanged(QString addonsPath);
void progressChanged(int progress);
void totalChanged(int total);
@@ -171,12 +169,15 @@ signals:
void updateStatusChanged(UpdateStatus updateStatus);
void addonsPathsChanged(QStringList addonsPaths);
void addonsPathChanged(int i, QString path);
public slots:
void setAddons(QList<QObject *> addons);
void setAddonsPath(QString addonsPath);
void saveAddonsPath();
void scanForAddons();
void clone(QUrl url);
void saveAddonsPaths();
void scanForAddons(int i = -1);
void clone(QUrl url, int i);
void setProgress(int progress);
void setTotal(int total);
void setStatus(Status status);
@@ -189,6 +190,8 @@ public slots:
void downloadUpdate();
void executeUpdate();
void setUpdateStatus(UpdateStatus updateStatus);
void setAddonsPaths(QStringList addonsPaths);
void setAddonsPath(int i, QString path = QString());
};
Q_DECLARE_METATYPE(Control::MinimizeToTray)
+4 -9
View File
@@ -93,11 +93,6 @@ ApplicationWindow {
onTriggered: updateAll()
enabled: availableUpdates > 0
}
Action {
id: openAddonsFolder
icon.name: "go-parent-folder"
onTriggered: Qt.openUrlExternally((Qt.platform.os == "windows" ? "file:///" : "file://")+Engine.addonsPath)
}
ColumnLayout{
anchors.fill: parent
@@ -186,11 +181,11 @@ ApplicationWindow {
}
FileDialog {
id: fileDialog
property int selector: -1
title: qsTr("Choose addons directory")
folder: Engine.addonsPath != "" ? Engine.addonsPath : shortcuts.home
onAccepted: Engine.addonsPath = fileUrl.toString().replace("file://","")
onAccepted: Engine.setAddonsPath(selector, fileUrl.toString().replace("file://",""))
selectFolder: true
visible: Engine.addonsPath == ""
visible: Engine.addonsPaths.length == 0
}
Dialog {
parent: ApplicationWindow.overlay
@@ -290,7 +285,7 @@ ApplicationWindow {
Dialog {
x: (parent.width - width) / 2
y: (parent.height - height) / 2
visible: Engine.addonsPath != "" && !Engine.addonsPath.toLowerCase().match("interface/addons$")
visible: Engine.addonsPaths[0] != "" && !Engine.addonsPaths[0].toLowerCase().match("interface/addons$")
title: qsTr("Warning")
Label {
anchors.fill: parent