1
0
Fork 0

Launcher: enable/disable all add-on types

Allow enable/disable in the UI of everything in the ‘add-ons’ page of
the launcher.
This commit is contained in:
James Turner 2020-02-24 11:32:43 +00:00
parent 32d6f75305
commit 410c249ba8
20 changed files with 467 additions and 160 deletions

View file

@ -22,12 +22,15 @@
#include "AddonsModel.hxx"
#include "InstallSceneryDialog.hxx"
#include "QtLauncher.hxx"
#include "PathListModel.hxx"
#include "LaunchConfig.hxx"
//////////////////////////////////////////////////////////////////////////
AddOnsController::AddOnsController(LauncherMainWindow *parent) :
AddOnsController::AddOnsController(LauncherMainWindow *parent, LaunchConfig* config) :
QObject(parent),
m_launcher(parent)
m_launcher(parent),
m_config(config)
{
m_catalogs = new CatalogListModel(this,
simgear::pkg::RootRef(globals->packageRoot()));
@ -38,10 +41,25 @@ AddOnsController::AddOnsController(LauncherMainWindow *parent) :
connect(m_addonsModuleModel, &AddonsModel::modulesChanged, this, &AddOnsController::onAddonsChanged);
using namespace flightgear::addons;
QSettings settings;
m_sceneryPaths = settings.value("scenery-paths").toStringList();
m_aircraftPaths = settings.value("aircraft-paths").toStringList();
m_sceneryPaths = new PathListModel(this);
connect(m_sceneryPaths, &PathListModel::enabledPathsChanged, [this] () {
m_sceneryPaths->saveToSettings("scenery-paths");
flightgear::launcherSetSceneryPaths();
});
m_sceneryPaths->loadFromSettings("scenery-paths");
m_aircraftPaths = new PathListModel(this);
connect(m_aircraftPaths, &PathListModel::enabledPathsChanged, [this] () {
m_aircraftPaths->saveToSettings("aircraft-paths");
auto aircraftCache = LocalAircraftCache::instance();
aircraftCache->setPaths(m_aircraftPaths->enabledPaths());
aircraftCache->scanDirs();
});
m_aircraftPaths->loadFromSettings("aircraft-paths");
QSettings settings;
int size = settings.beginReadArray("addon-modules");
for (int i = 0; i < size; ++i) {
settings.setArrayIndex(i);
@ -66,14 +84,18 @@ AddOnsController::AddOnsController(LauncherMainWindow *parent) :
qmlRegisterUncreatableType<AddOnsController>("FlightGear.Launcher", 1, 0, "AddOnsControllers", "no");
qmlRegisterUncreatableType<CatalogListModel>("FlightGear.Launcher", 1, 0, "CatalogListModel", "no");
qmlRegisterUncreatableType<AddonsModel>("FlightGear.Launcher", 1, 0, "AddonsModel", "no");
qmlRegisterUncreatableType<PathListModel>("FlightGear.Launcher", 1, 0, "PathListMode", "no");
connect(m_config, &LaunchConfig::collect,
this, &AddOnsController::collectArgs);
}
QStringList AddOnsController::aircraftPaths() const
PathListModel* AddOnsController::aircraftPaths() const
{
return m_aircraftPaths;
}
QStringList AddOnsController::sceneryPaths() const
PathListModel* AddOnsController::sceneryPaths() const
{
return m_sceneryPaths;
}
@ -119,6 +141,7 @@ QString AddOnsController::addAircraftPath() const
}
}
m_aircraftPaths->appendPath(path);
return path;
}
@ -206,6 +229,7 @@ QString AddOnsController::addSceneryPath() const
}
}
m_sceneryPaths->appendPath(path);
return path;
}
@ -227,37 +251,6 @@ void AddOnsController::openDirectory(QString path)
QDesktopServices::openUrl(u);
}
void AddOnsController::setAircraftPaths(QStringList aircraftPaths)
{
if (m_aircraftPaths == aircraftPaths)
return;
m_aircraftPaths = aircraftPaths;
emit aircraftPathsChanged(m_aircraftPaths);
QSettings settings;
settings.setValue("aircraft-paths", m_aircraftPaths);
auto aircraftCache = LocalAircraftCache::instance();
aircraftCache->setPaths(m_aircraftPaths);
aircraftCache->scanDirs();
}
void AddOnsController::setSceneryPaths(QStringList sceneryPaths)
{
if (m_sceneryPaths == sceneryPaths)
return;
m_sceneryPaths = sceneryPaths;
QSettings settings;
settings.setValue("scenery-paths", m_sceneryPaths);
flightgear::launcherSetSceneryPaths();
emit sceneryPathsChanged(m_sceneryPaths);
}
void AddOnsController::setAddons(AddonsModel* addons)
{
@ -342,3 +335,31 @@ void AddOnsController::onAddonsChanged()
}
settings.endArray();
}
void AddOnsController::collectArgs()
{
// scenery paths
Q_FOREACH(QString path, m_sceneryPaths->enabledPaths()) {
m_config->setArg("fg-scenery", path);
}
// aircraft paths
Q_FOREACH(QString path, m_aircraftPaths->enabledPaths()) {
m_config->setArg("fg-aircraft", path);
}
// add-on module paths
// we could query this directly from AddonsModel, but this is simpler right now
QSettings settings;
int size = settings.beginReadArray("addon-modules");
for (int i = 0; i < size; ++i) {
settings.setArrayIndex(i);
QString path = settings.value("path").toString();
bool enable = settings.value("enable").toBool();
if (enable) {
m_config->setArg("addon", path);
}
}
settings.endArray();
}

View file

@ -7,13 +7,15 @@
class CatalogListModel;
class AddonsModel;
class LauncherMainWindow;
class PathListModel;
class LaunchConfig;
class AddOnsController : public QObject
{
Q_OBJECT
Q_PROPERTY(QStringList aircraftPaths READ aircraftPaths WRITE setAircraftPaths NOTIFY aircraftPathsChanged)
Q_PROPERTY(QStringList sceneryPaths READ sceneryPaths WRITE setSceneryPaths NOTIFY sceneryPathsChanged)
Q_PROPERTY(PathListModel* aircraftPaths READ aircraftPaths CONSTANT)
Q_PROPERTY(PathListModel* sceneryPaths READ sceneryPaths CONSTANT)
Q_PROPERTY(QStringList modulePaths READ modulePaths WRITE setModulePaths NOTIFY modulePathsChanged)
Q_PROPERTY(CatalogListModel* catalogs READ catalogs CONSTANT)
@ -22,10 +24,10 @@ class AddOnsController : public QObject
Q_PROPERTY(bool showNoOfficialHangar READ showNoOfficialHangar NOTIFY showNoOfficialHangarChanged)
public:
explicit AddOnsController(LauncherMainWindow *parent = nullptr);
explicit AddOnsController(LauncherMainWindow *parent, LaunchConfig* config);
QStringList aircraftPaths() const;
QStringList sceneryPaths() const;
PathListModel* aircraftPaths() const;
PathListModel* sceneryPaths() const;
QStringList modulePaths() const;
CatalogListModel* catalogs() const
@ -50,8 +52,6 @@ public:
Q_INVOKABLE void officialCatalogAction(QString s);
signals:
void aircraftPathsChanged(QStringList aircraftPaths);
void sceneryPathsChanged(QStringList sceneryPaths);
void modulePathsChanged(QStringList modulePaths);
void modulesChanged();
@ -59,12 +59,12 @@ signals:
void showNoOfficialHangarChanged();
public slots:
void setAircraftPaths(QStringList aircraftPaths);
void setSceneryPaths(QStringList sceneryPaths);
void setModulePaths(QStringList modulePaths);
void setAddons(AddonsModel* addons);
void onAddonsChanged(void);
void collectArgs();
private:
bool shouldShowOfficialCatalogMessage() const;
void onCatalogsChanged();
@ -72,9 +72,10 @@ private:
LauncherMainWindow* m_launcher;
CatalogListModel* m_catalogs = nullptr;
AddonsModel* m_addonsModuleModel = nullptr;
LaunchConfig* m_config = nullptr;
QStringList m_aircraftPaths;
QStringList m_sceneryPaths;
PathListModel* m_aircraftPaths = nullptr;
PathListModel* m_sceneryPaths = nullptr;
QStringList m_addonModulePaths;
};

View file

@ -42,6 +42,19 @@ const int STANDARD_THUMBNAIL_HEIGHT = 128;
using namespace simgear::pkg;
bool isPackageFailure(Delegate::StatusCode status)
{
switch (status) {
case Delegate::STATUS_SUCCESS:
case Delegate::STATUS_REFRESHED:
case Delegate::STATUS_IN_PROGRESS:
return false;
default:
return true;
}
}
class PackageDelegate : public simgear::pkg::Delegate
{
public:
@ -77,8 +90,8 @@ protected:
void installProgress(InstallRef aInstall, unsigned int bytes, unsigned int total) override
{
Q_UNUSED(bytes);
Q_UNUSED(total);
Q_UNUSED(bytes)
Q_UNUSED(total)
QModelIndex mi(indexForPackage(aInstall->package()));
m_model->dataChanged(mi, mi);
}
@ -104,7 +117,7 @@ protected:
void installStatusChanged(InstallRef aInstall, StatusCode aReason) override
{
Q_UNUSED(aReason);
Q_UNUSED(aReason)
QModelIndex mi(indexForPackage(aInstall->package()));
m_model->dataChanged(mi, mi);
}
@ -261,7 +274,7 @@ QVariant AircraftItemModel::data(const QModelIndex& index, int role) const
}
if (row >= m_cachedLocalAircraftCount) {
quint32 packageIndex = row - m_cachedLocalAircraftCount;
quint32 packageIndex = static_cast<quint32>(row - m_cachedLocalAircraftCount);
const PackageRef& pkg(m_packages[packageIndex]);
InstallRef ex = pkg->existingInstall();
@ -393,6 +406,10 @@ QVariant AircraftItemModel::dataFromPackage(const PackageRef& item, const Delega
return LocalAircraftCache::PackageUpdateAvailable;
}
const auto status = i->status();
if (isPackageFailure(status))
return LocalAircraftCache::PackageInstallFailed;
return LocalAircraftCache::PackageInstalled;
} else {
return LocalAircraftCache::PackageNotInstalled;

View file

@ -124,6 +124,8 @@ if (HAVE_QT)
AddonsModel.hxx
PixmapImageItem.cxx
PixmapImageItem.hxx
PathListModel.cxx
PathListModel.hxx
${uic_sources}
${qrc_sources}
${qml_sources})

View file

@ -93,13 +93,13 @@ void CatalogListModel::resetData()
int CatalogListModel::rowCount(const QModelIndex& parent) const
{
return m_catalogs.size();
Q_UNUSED(parent)
return static_cast<int>(m_catalogs.size());
}
QVariant CatalogListModel::data(const QModelIndex& index, int role) const
{
simgear::pkg::CatalogRef cat = m_catalogs.at(index.row());
const auto cat = m_catalogs.at(static_cast<size_t>(index.row()));
if (role == Qt::DisplayRole) {
QString name = QString::fromStdString(cat->name());
QString desc;
@ -139,6 +139,8 @@ QVariant CatalogListModel::data(const QModelIndex& index, int role) const
return translateStatusForCatalog(cat);
} else if (role == CatalogIsNewlyAdded) {
return (cat == m_newlyAddedCatalog);
} else if (role == CatalogEnabled) {
return cat->isUserEnabled();
}
return QVariant();
@ -146,13 +148,18 @@ QVariant CatalogListModel::data(const QModelIndex& index, int role) const
bool CatalogListModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
auto cat = m_catalogs.at(static_cast<size_t>(index.row()));
if (role == CatalogEnabled) {
cat->setUserEnabled(value.toBool());
return true;
}
return false;
}
Qt::ItemFlags CatalogListModel::flags(const QModelIndex &index) const
{
Qt::ItemFlags r = Qt::ItemIsSelectable;
const auto cat = m_catalogs.at(index.row());
const auto cat = m_catalogs.at(static_cast<size_t>(index.row()));
if (cat->isEnabled()) {
r |= Qt::ItemIsEnabled;
}
@ -168,28 +175,27 @@ QHash<int, QByteArray> CatalogListModel::roleNames() const
result[CatalogNameRole] = "name";
result[CatalogStatusRole] = "status";
result[CatalogIsNewlyAdded] = "isNewlyAdded";
result[CatalogEnabled] = "enabled";
return result;
}
void CatalogListModel::removeCatalog(int index)
{
if ((index < 0) || (index >= m_catalogs.size())) {
if ((index < 0) || (index >= static_cast<int>(m_catalogs.size()))) {
return;
}
const std::string removeId = m_catalogs.at(index)->id();
const std::string removeId = m_catalogs.at(static_cast<size_t>(index))->id();
m_packageRoot->removeCatalogById(removeId);
resetData();
}
void CatalogListModel::refreshCatalog(int index)
{
if ((index < 0) || (index >= m_catalogs.size())) {
if ((index < 0) || (index >= static_cast<int>(m_catalogs.size()))) {
return;
}
m_catalogs.at(index)->refresh();
m_catalogs.at(static_cast<size_t>(index))->refresh();
}
void CatalogListModel::installDefaultCatalog()
@ -221,7 +227,7 @@ int CatalogListModel::indexOf(QUrl url)
if (it == m_catalogs.end())
return -1;
return std::distance(m_catalogs.begin(), it);
return static_cast<int>(std::distance(m_catalogs.begin(), it));
}
void CatalogListModel::finalizeAddCatalog()
@ -237,7 +243,7 @@ void CatalogListModel::finalizeAddCatalog()
return;
}
const int row = std::distance(m_catalogs.begin(), it);
const int row = static_cast<int>(std::distance(m_catalogs.begin(), it));
m_newlyAddedCatalog.clear();
emit isAddingCatalogChanged();
emit statusOfAddingCatalogChanged();

View file

@ -38,6 +38,7 @@ const int CatalogStatusRole = Qt::UserRole + 5;
const int CatalogDescriptionRole = Qt::UserRole + 6;
const int CatalogNameRole = Qt::UserRole + 7;
const int CatalogIsNewlyAdded = Qt::UserRole + 8;
const int CatalogEnabled = Qt::UserRole + 9;
class CatalogDelegate;

View file

@ -102,8 +102,6 @@ LauncherController::LauncherController(QObject *parent, QWindow* window) :
this, &LauncherController::updateSelectedAircraft);
QSettings settings;
LocalAircraftCache::instance()->setPaths(settings.value("aircraft-paths").toStringList());
LocalAircraftCache::instance()->scanDirs();
m_aircraftModel->setPackageRoot(globals->packageRoot());
m_aircraftGridMode = settings.value("aircraftGridMode").toBool();
@ -280,31 +278,6 @@ void LauncherController::collectAircraftArgs()
m_config->setArg("state", state);
}
}
// scenery paths
QSettings settings;
Q_FOREACH(QString path, settings.value("scenery-paths").toStringList()) {
m_config->setArg("fg-scenery", path);
}
// aircraft paths
Q_FOREACH(QString path, settings.value("aircraft-paths").toStringList()) {
m_config->setArg("fg-aircraft", path);
}
// add-on module paths
int size = settings.beginReadArray("addon-modules");
for (int i = 0; i < size; ++i) {
settings.setArrayIndex(i);
QString path = settings.value("path").toString();
bool enable = settings.value("enable").toBool();
if (enable) {
m_config->setArg("addon", path);
}
}
settings.endArray();
}
void LauncherController::saveAircraft()

View file

@ -68,9 +68,8 @@ LauncherMainWindow::LauncherMainWindow() :
connect(qa, &QAction::triggered, m_controller, &LauncherController::quit);
m_controller->initialRestoreSettings();
flightgear::launcherSetSceneryPaths();
auto addOnsCtl = new AddOnsController(this);
auto addOnsCtl = new AddOnsController(this, m_controller->config());
////////////
#if defined(Q_OS_WIN)

View file

@ -126,7 +126,8 @@ public:
PackageUpdateAvailable,
PackageQueued,
PackageDownloading,
NotPackaged
NotPackaged,
PackageInstallFailed
};
Q_ENUMS(PackageStatus)

188
src/GUI/PathListModel.cxx Normal file
View file

@ -0,0 +1,188 @@
#include "PathListModel.hxx"
#include <QSettings>
#include <QDebug>
PathListModel::PathListModel(QObject *pr) :
QAbstractListModel(pr)
{
}
PathListModel::~PathListModel()
{
}
void PathListModel::loadFromSettings(QString key)
{
QSettings settings;
if (!settings.contains(key))
return;
QVariantList vl = settings.value(key).toList();
mPaths.clear();
mPaths.reserve(static_cast<size_t>(vl.size()));
beginResetModel();
Q_FOREACH(QVariant v, vl) {
QVariantMap m = v.toMap();
PathEntry entry;
entry.path = m.value("path").toString();
if (entry.path.isEmpty()) {
continue;
}
entry.enabled = m.value("enabled", QVariant{true}).toBool();
mPaths.push_back(entry);
}
endResetModel();
emit enabledPathsChanged();
emit countChanged();
}
void PathListModel::saveToSettings(QString key) const
{
QVariantList vl;
for (const auto &e : mPaths) {
QVariantMap v;
v["path"] = e.path;
v["enabled"] = e.enabled;
vl.append(v);
}
QSettings settings;
settings.setValue(key, vl);
}
QStringList PathListModel::readEnabledPaths(QString settingsKey)
{
QSettings settings;
if (!settings.contains(settingsKey))
return {};
QStringList result;
QVariantList vl = settings.value(settingsKey).toList();
Q_FOREACH(QVariant v, vl) {
QVariantMap m = v.toMap();
if (!m.value("enabled").toBool())
continue;
result.append(m.value("path").toString());
}
return result;
}
QStringList PathListModel::enabledPaths() const
{
QStringList result;
for (const auto& e : mPaths) {
if (e.enabled) {
result.append(e.path);
}
}
return result;
}
int PathListModel::count()
{
return static_cast<int>(mPaths.size());
}
int PathListModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return static_cast<int>(mPaths.size());
}
QVariant PathListModel::data(const QModelIndex &index, int role) const
{
int row = index.row();
const auto& entry = mPaths.at(static_cast<size_t>(row));
switch (role) {
case Qt::DisplayRole:
case PathRole:
return entry.path;
case PathEnabledRole:
return entry.enabled;
default:
break;
}
return {};
}
bool PathListModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
int row = index.row();
auto& entry = mPaths.at(static_cast<size_t>(row));
if (role == PathEnabledRole) {
entry.enabled = value.toBool();
emit dataChanged(index, index, {PathEnabledRole});
emit enabledPathsChanged();
return true;
}
return false;
}
QHash<int, QByteArray> PathListModel::roleNames() const
{
QHash<int, QByteArray> result = QAbstractListModel::roleNames();
result[Qt::DisplayRole] = "path";
result[PathEnabledRole] = "enabled";
return result;
}
void PathListModel::removePath(int index)
{
if ((index < 0) || (index >= static_cast<int>(mPaths.size()))) {
qWarning() << Q_FUNC_INFO << "index invalid:" << index;
return;
}
beginRemoveRows({}, index, index);
auto it = mPaths.begin() + index;
mPaths.erase(it);
endRemoveRows();
emit enabledPathsChanged();
emit countChanged();
}
void PathListModel::appendPath(QString path)
{
PathEntry entry;
entry.path = path;
entry.enabled = true; // enable by default
const int newRow = static_cast<int>(mPaths.size());
beginInsertRows({}, newRow, newRow);
mPaths.push_back(entry);
endInsertRows();
emit enabledPathsChanged();
emit countChanged();
}
void PathListModel::sawpIndices(int indexA, int indexB)
{
if ((indexA < 0) || (indexA >= static_cast<int>(mPaths.size()))) {
qWarning() << Q_FUNC_INFO << "index invalid:" << indexA;
return;
}
if ((indexB < 0) || (indexB >= static_cast<int>(mPaths.size()))) {
qWarning() << Q_FUNC_INFO << "index invalid:" << indexB;
return;
}
std::swap(mPaths[static_cast<size_t>(indexA)],
mPaths[static_cast<size_t>(indexB)]);
emit dataChanged(index(indexA), index(indexA));
emit dataChanged(index(indexB), index(indexB));
emit enabledPathsChanged();
}

56
src/GUI/PathListModel.hxx Normal file
View file

@ -0,0 +1,56 @@
#ifndef PATHLISTMODEL_HXX
#define PATHLISTMODEL_HXX
#include <vector>
#include <QAbstractListModel>
const int PathRole = Qt::UserRole + 1;
const int PathEnabledRole = Qt::UserRole + 2;
class PathListModel : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(int count READ count NOTIFY countChanged)
public:
PathListModel(QObject* pr);
~PathListModel() override;
void loadFromSettings(QString key);
void saveToSettings(QString key) const;
int rowCount(const QModelIndex& parent) const override;
QVariant data(const QModelIndex& index, int role) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
QHash<int, QByteArray> roleNames() const override;
static QStringList readEnabledPaths(QString settingsKey);
QStringList enabledPaths() const;
int count();
signals:
void enabledPathsChanged();
void countChanged();
public slots:
void removePath(int index);
void appendPath(QString path);
void sawpIndices(int indexA, int indexB);
private:
struct PathEntry {
QString path;
bool enabled = true;
};
std::vector<PathEntry> mPaths;
};
#endif // PATHLISTMODEL_HXX

View file

@ -74,6 +74,7 @@
#include "LauncherMainWindow.hxx"
#include "LaunchConfig.hxx"
#include "UnitsModel.hxx"
#include "PathListModel.hxx"
using namespace flightgear;
using namespace simgear::pkg;
@ -403,7 +404,7 @@ void launcherSetSceneryPaths()
// positions
QSettings settings;
// append explicit scenery paths
Q_FOREACH(QString path, settings.value("scenery-paths").toStringList()) {
Q_FOREACH(QString path, PathListModel::readEnabledPaths("scenery-paths")) {
globals->append_fg_scenery(path.toStdString());
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

View file

@ -102,12 +102,7 @@ Item {
description: qsTr("To use aircraft you download yourself, FlightGear needs to " +
"know the folder(s) containing the aircraft data.")
showAddButton: true
onAdd: {
var newPath =_addOns.addAircraftPath();
if (newPath !== "") {
_addOns.aircraftPaths.push(newPath)
}
}
onAdd: _addOns.addAircraftPath();
}
Rectangle {
@ -127,21 +122,10 @@ Item {
model: _addOns.aircraftPaths
delegate: PathListDelegate {
width: aircraftPathsColumn.width
deletePromptText: qsTr("Remove the aircraft folder: '%1' from the list? (The folder contents will not be changed)").arg(modelData);
modelCount: _addOns.aircraftPaths.length
onPerformDelete: {
var modifiedPaths = _addOns.aircraftPaths.slice()
modifiedPaths.splice(model.index, 1);
_addOns.aircraftPaths = modifiedPaths;
}
onPerformMove: {
var modifiedPaths = _addOns.aircraftPaths.slice()
modifiedPaths.splice(model.index, 1);
modifiedPaths.splice(newIndex, 0, modelData)
_addOns.aircraftPaths = modifiedPaths;
}
deletePromptText: qsTr("Remove the aircraft folder: '%1' from the list? (The folder contents will not be changed)").arg(model.path);
modelCount: _addOns.aircraftPaths.count
onPerformDelete: _addOns.aircraftPaths.removePath(model.index)
onPerformMove: _addOns.aircraftPaths.sawpIndices(model.index, newIndex);
}
}
@ -241,12 +225,7 @@ Item {
"to know the folders containing the scenery data. " +
"Adjust the order of the list to control which scenery is used in a region.");
showAddButton: true
onAdd: {
var newPath =_addOns.addSceneryPath();
if (newPath !== "") {
_addOns.sceneryPaths.push(newPath)
}
}
onAdd: _addOns.addSceneryPath();
}
Rectangle {
@ -267,21 +246,10 @@ Item {
delegate: PathListDelegate {
width: sceneryPathsColumn.width
deletePromptText: qsTr("Remove the scenery folder: '%1' from the list? (The folder contents will not be changed)").arg(modelData);
modelCount: _addOns.sceneryPaths.length
onPerformDelete: {
var modifiedPaths = _addOns.sceneryPaths.slice()
modifiedPaths.splice(model.index, 1);
_addOns.sceneryPaths = modifiedPaths;
}
onPerformMove: {
var modifiedPaths = _addOns.sceneryPaths.slice()
modifiedPaths.splice(model.index, 1);
modifiedPaths.splice(newIndex, 0, modelData)
_addOns.sceneryPaths = modifiedPaths;
}
deletePromptText: qsTr("Remove the scenery folder: '%1' from the list? (The folder contents will not be changed)").arg(model.path);
modelCount: _addOns.sceneryPaths.count
onPerformDelete: _addOns.sceneryPaths.removePath(model.index)
onPerformMove: _addOns.sceneryPaths.swapIndices(model.index, newIndex);
}
}
@ -304,14 +272,10 @@ Item {
var path = _addOns.installCustomScenery();
if (path !== "") {
// insert into scenery paths if not already present
var sceneryPaths = _addOns.sceneryPaths
for (var i = 0; i < sceneryPaths.length; i++) {
if (sceneryPaths[i] === path)
return; // found, we are are done
}
// not found, add it
_addOns.sceneryPaths.push(path);
_addOns.sceneryPaths.appendPath(path);
}
}
}

View file

@ -41,12 +41,9 @@ Item {
width: delegateRoot.width
Checkbox {
id: chkbox
id: enableCheckbox
checked: model.enable
width: 30
anchors.left: parent.left
anchors.right: addonsDelegateHover.left
anchors.rightMargin: Style.margin
height: contentRect.height
onCheckedChanged: {
_addOns.modules.enable(model.index, checked)
@ -59,7 +56,7 @@ Item {
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.left: chkbox.right
anchors.left: enableCheckbox.right
hoverEnabled: true
acceptedButtons: Qt.NoButton

View file

@ -26,12 +26,19 @@ Item {
}
}
function isDisabled()
{
return (model.status !== CatalogListModel.Ok) ||
(enableCheckbox.checked === false);
}
Item
{
anchors.top: divider.bottom
height: catalogTextColumn.childrenRect.height + Style.margin * 2
width: parent.width
Column {
id: catalogTextColumn
@ -42,11 +49,28 @@ Item {
anchors.rightMargin: Style.margin
spacing: Style.margin
StyledText {
font.pixelSize: Style.subHeadingFontPixelSize
font.bold: true
width: parent.width
text: model.name
Row {
spacing: Style.margin
height: headingText.height
Checkbox {
id: enableCheckbox
checked: model.enabled
height: parent.height
onCheckedChanged: model.enable = checked;
// only allow the user to toggle enable/disable if
// the catalog is valid
visible: (model.status === CatalogListModel.Ok)
}
StyledText {
id: headingText
font.pixelSize: Style.subHeadingFontPixelSize
font.bold: true
width: catalogTextColumn.width - enableCheckbox.width
text: model.name
font.strikeout: delegateRoot.isDisabled();
}
}
StyledText {

View file

@ -1,4 +1,5 @@
import QtQuick 2.4
import "."
Item {
property bool checked: false
@ -11,7 +12,7 @@ Item {
id: checkBox
width: 18
height: 18
border.color: mouseArea.containsMouse ? "#68A6E1" : "#9f9f9f"
border.color: mouseArea.containsMouse ? Style.frameColor : Style.inactiveThemeColor
border.width: 1
anchors.left: parent.left
anchors.leftMargin: 8
@ -22,7 +23,7 @@ Item {
height: 12
anchors.centerIn: parent
id: checkMark
color: "#9f9f9f"
color: Style.themeColor
visible: checked
}
}
@ -41,5 +42,6 @@ Item {
onClicked: {
checked = !checked
}
cursorShape: Qt.PointingHandCursor
}
}

View file

@ -0,0 +1,36 @@
import QtQuick 2.0
import "."
Item {
id: root
width: height
height: icon.implicitHeight + 1
property bool enable: true
signal clicked();
Image {
id: icon
source: "qrc:///svg/icon-hide"
}
MouseArea {
id: mouse
// hoverEnabled: true
onClicked: root.clicked();
anchors.fill: parent
}
// Text {
// anchors.right: root.left
// anchors.rightMargin: Style.margin
// anchors.verticalCenter: root.verticalCenter
// visible: mouse.containsMouse
// color: Style.baseTextColor
// font.pixelSize: Style.baseFontPixelSize
// text: root.enable ? qsTr("Click_to_disable")
// : qsTr("Click_to_enable")
// }
}

View file

@ -36,9 +36,23 @@ Item {
height: Math.max(label.implicitHeight, pathDeleteButton.height)
width: delegateRoot.width
Checkbox {
id: enableCheckbox
checked: model.enabled
anchors.left: parent.left
height: parent.height
onCheckedChanged: {
model.enabled = checked;
}
}
MouseArea {
id: pathDelegateHover
anchors.fill: parent
anchors.left: enableCheckbox.right
anchors.leftMargin: Style.margin
anchors.right: parent.right
height: parent.height
hoverEnabled: true
acceptedButtons: Qt.NoButton
@ -46,10 +60,10 @@ Item {
// MouseArea, so nested containsMouse logic works
ClickableText {
id: label
text: modelData
text: model.path
onClicked: {
// open the location
_addOns.openDirectory(modelData)
_addOns.openDirectory(model.path)
}
anchors.left: parent.left
anchors.right: reorderButton.left
@ -58,6 +72,8 @@ Item {
verticalAlignment: Text.AlignVCenter
wrapMode: Text.WordWrap
font.strikeout: enableCheckbox.checked === false
}
DeleteButton {
@ -88,7 +104,7 @@ Item {
delegateRoot.performMove(model.index + 1)
}
}
}
} // of MouseArea for hover
YesNoPanel {
id: confirmDeletePath

View file

@ -129,6 +129,7 @@
<file>qml/AircraftGridView.qml</file>
<file>qml/AircraftListView.qml</file>
<file>qml/GridToggleButton.qml</file>
<file>qml/EnableDisableButton.qml</file>
</qresource>
<qresource prefix="/preview">
<file alias="close-icon">preview-close.png</file>
@ -147,5 +148,6 @@
<file alias="toolbox-fly-heli">assets/icons8-helicopter.svg</file>
<file alias="icon-grid-view">assets/icons8-grid-view.svg</file>
<file alias="icon-list-view">assets/icons8-menu.svg</file>
<file alias="icon-hide">assets/icons8-hide-50.png</file>
</qresource>
</RCC>