Move some Launcher helpers into their own files.
Suggested be Sebastian, and it’s a good idea indeed, the main launcher file has grown slightly.
This commit is contained in:
parent
bf1ffb8875
commit
4234876789
6 changed files with 289 additions and 243 deletions
113
src/GUI/AircraftSearchFilterModel.cxx
Normal file
113
src/GUI/AircraftSearchFilterModel.cxx
Normal file
|
@ -0,0 +1,113 @@
|
|||
#include "AircraftSearchFilterModel.hxx"
|
||||
|
||||
#include "AircraftModel.hxx"
|
||||
#include <simgear/package/Package.hxx>
|
||||
|
||||
AircraftProxyModel::AircraftProxyModel(QObject *pr) :
|
||||
QSortFilterProxyModel(pr)
|
||||
{
|
||||
}
|
||||
|
||||
void AircraftProxyModel::setRatings(int *ratings)
|
||||
{
|
||||
::memcpy(m_ratings, ratings, sizeof(int) * 4);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void AircraftProxyModel::setAircraftFilterString(QString s)
|
||||
{
|
||||
m_filterString = s;
|
||||
|
||||
m_filterProps = new SGPropertyNode;
|
||||
int index = 0;
|
||||
Q_FOREACH(QString term, s.split(' ')) {
|
||||
m_filterProps->getNode("all-of/text", index++, true)->setStringValue(term.toStdString());
|
||||
}
|
||||
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void AircraftProxyModel::setRatingFilterEnabled(bool e)
|
||||
{
|
||||
if (e == m_ratingsFilter) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_ratingsFilter = e;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void AircraftProxyModel::setInstalledFilterEnabled(bool e)
|
||||
{
|
||||
if (e == m_onlyShowInstalled) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_onlyShowInstalled = e;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
bool AircraftProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
|
||||
{
|
||||
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||
QVariant v = index.data(AircraftPackageStatusRole);
|
||||
AircraftItemStatus status = static_cast<AircraftItemStatus>(v.toInt());
|
||||
if (status == MessageWidget) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!filterAircraft(index)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_onlyShowInstalled) {
|
||||
QVariant v = index.data(AircraftPackageStatusRole);
|
||||
AircraftItemStatus status = static_cast<AircraftItemStatus>(v.toInt());
|
||||
if (status == PackageNotInstalled) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_onlyShowInstalled && m_ratingsFilter) {
|
||||
for (int i=0; i<4; ++i) {
|
||||
if (m_ratings[i] > index.data(AircraftRatingRole + i).toInt()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AircraftProxyModel::filterAircraft(const QModelIndex &sourceIndex) const
|
||||
{
|
||||
if (m_filterString.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
simgear::pkg::PackageRef pkg = sourceIndex.data(AircraftPackageRefRole).value<simgear::pkg::PackageRef>();
|
||||
if (pkg) {
|
||||
return pkg->matches(m_filterProps.ptr());
|
||||
}
|
||||
|
||||
QString baseName = sourceIndex.data(Qt::DisplayRole).toString();
|
||||
if (baseName.contains(m_filterString, Qt::CaseInsensitive)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
QString longDesc = sourceIndex.data(AircraftLongDescriptionRole).toString();
|
||||
if (longDesc.contains(m_filterString, Qt::CaseInsensitive)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const int variantCount = sourceIndex.data(AircraftVariantCountRole).toInt();
|
||||
for (int variant = 0; variant < variantCount; ++variant) {
|
||||
QString desc = sourceIndex.data(AircraftVariantDescriptionRole + variant).toString();
|
||||
if (desc.contains(m_filterString, Qt::CaseInsensitive)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
36
src/GUI/AircraftSearchFilterModel.hxx
Normal file
36
src/GUI/AircraftSearchFilterModel.hxx
Normal file
|
@ -0,0 +1,36 @@
|
|||
#ifndef AIRCRAFTSEARCHFILTERMODEL_HXX
|
||||
#define AIRCRAFTSEARCHFILTERMODEL_HXX
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
#include <simgear/props/props.hxx>
|
||||
|
||||
class AircraftProxyModel : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AircraftProxyModel(QObject* pr);
|
||||
|
||||
void setRatings(int* ratings);
|
||||
|
||||
void setAircraftFilterString(QString s);
|
||||
|
||||
public slots:
|
||||
void setRatingFilterEnabled(bool e);
|
||||
|
||||
void setInstalledFilterEnabled(bool e);
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
|
||||
private:
|
||||
bool filterAircraft(const QModelIndex& sourceIndex) const;
|
||||
|
||||
bool m_ratingsFilter = true;
|
||||
bool m_onlyShowInstalled = false;
|
||||
int m_ratings[4] = {3, 3, 3, 3};
|
||||
QString m_filterString;
|
||||
SGPropertyNode_ptr m_filterProps;
|
||||
};
|
||||
|
||||
#endif // AIRCRAFTSEARCHFILTERMODEL_HXX
|
|
@ -143,6 +143,10 @@ if (HAVE_QT)
|
|||
EnvironmentPage.h
|
||||
AdditionalSettings.cpp
|
||||
AdditionalSettings.h
|
||||
LauncherArgumentTokenizer.cxx
|
||||
LauncherArgumentTokenizer.hxx
|
||||
AircraftSearchFilterModel.cxx
|
||||
AircraftSearchFilterModel.hxx
|
||||
${uic_sources}
|
||||
${qrc_sources})
|
||||
|
||||
|
|
97
src/GUI/LauncherArgumentTokenizer.cxx
Normal file
97
src/GUI/LauncherArgumentTokenizer.cxx
Normal file
|
@ -0,0 +1,97 @@
|
|||
#include "LauncherArgumentTokenizer.hxx"
|
||||
|
||||
LauncherArgumentTokenizer::LauncherArgumentTokenizer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QList<LauncherArgumentTokenizer::Arg> LauncherArgumentTokenizer::tokenize(QString in) const
|
||||
{
|
||||
int index = 0;
|
||||
const int len = in.count();
|
||||
QChar c, nc;
|
||||
State state = Start;
|
||||
QString key, value;
|
||||
QList<Arg> result;
|
||||
|
||||
for (; index < len; ++index) {
|
||||
c = in.at(index);
|
||||
nc = index < (len - 1) ? in.at(index + 1) : QChar();
|
||||
|
||||
switch (state) {
|
||||
case Start:
|
||||
if (c == QChar('-')) {
|
||||
if (nc == QChar('-')) {
|
||||
state = Key;
|
||||
key.clear();
|
||||
++index;
|
||||
} else {
|
||||
// should we pemit single hyphen arguments?
|
||||
// choosing to fail for now
|
||||
return QList<Arg>();
|
||||
}
|
||||
} else if (c == QChar('#')) {
|
||||
state = Comment;
|
||||
break;
|
||||
} else if (c.isSpace()) {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case Key:
|
||||
if (c == QChar('=')) {
|
||||
state = Value;
|
||||
value.clear();
|
||||
} else if (c.isSpace()) {
|
||||
state = Start;
|
||||
result.append(Arg(key));
|
||||
} else {
|
||||
// could check for illegal charatcers here
|
||||
key.append(c);
|
||||
}
|
||||
break;
|
||||
|
||||
case Value:
|
||||
if (c == QChar('"')) {
|
||||
state = Quoted;
|
||||
} else if (c.isSpace()) {
|
||||
state = Start;
|
||||
result.append(Arg(key, value));
|
||||
} else {
|
||||
value.append(c);
|
||||
}
|
||||
break;
|
||||
|
||||
case Quoted:
|
||||
if (c == QChar('\\')) {
|
||||
// check for escaped double-quote inside quoted value
|
||||
if (nc == QChar('"')) {
|
||||
++index;
|
||||
}
|
||||
} else if (c == QChar('"')) {
|
||||
state = Value;
|
||||
} else {
|
||||
value.append(c);
|
||||
}
|
||||
break;
|
||||
|
||||
case Comment:
|
||||
if ((c == QChar('\n')) || (c == QChar('\r'))) {
|
||||
state = Start;
|
||||
break;
|
||||
} else {
|
||||
// nothing to do, eat comment chars
|
||||
}
|
||||
break;
|
||||
} // of state switch
|
||||
} // of character loop
|
||||
|
||||
// ensure last argument isn't lost
|
||||
if (state == Key) {
|
||||
result.append(Arg(key));
|
||||
} else if (state == Value) {
|
||||
result.append(Arg(key, value));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
34
src/GUI/LauncherArgumentTokenizer.hxx
Normal file
34
src/GUI/LauncherArgumentTokenizer.hxx
Normal file
|
@ -0,0 +1,34 @@
|
|||
#ifndef LAUNCHERARGUMENTTOKENIZER_HXX
|
||||
#define LAUNCHERARGUMENTTOKENIZER_HXX
|
||||
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
|
||||
class LauncherArgumentTokenizer
|
||||
{
|
||||
public:
|
||||
LauncherArgumentTokenizer();
|
||||
|
||||
class Arg
|
||||
{
|
||||
public:
|
||||
explicit Arg(QString k, QString v = QString()) : arg(k), value(v) {}
|
||||
|
||||
QString arg;
|
||||
QString value;
|
||||
};
|
||||
|
||||
QList<Arg> tokenize(QString in) const;
|
||||
|
||||
private:
|
||||
enum State {
|
||||
Start = 0,
|
||||
Key,
|
||||
Value,
|
||||
Quoted,
|
||||
Comment
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#endif // LAUNCHERARGUMENTTOKENIZER_HXX
|
|
@ -35,7 +35,6 @@
|
|||
#include <QCompleter>
|
||||
#include <QListView>
|
||||
#include <QSettings>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QMenu>
|
||||
#include <QDesktopServices>
|
||||
#include <QUrl>
|
||||
|
@ -70,6 +69,8 @@
|
|||
#include "PathsDialog.hxx"
|
||||
#include "EditCustomMPServerDialog.hxx"
|
||||
#include "previewwindow.h"
|
||||
#include "LauncherArgumentTokenizer.hxx"
|
||||
#include "AircraftSearchFilterModel.hxx"
|
||||
|
||||
#include <Main/globals.hxx>
|
||||
#include <Main/fg_props.hxx>
|
||||
|
@ -162,119 +163,6 @@ void initNavCache()
|
|||
}
|
||||
}
|
||||
|
||||
class ArgumentsTokenizer
|
||||
{
|
||||
public:
|
||||
class Arg
|
||||
{
|
||||
public:
|
||||
explicit Arg(QString k, QString v = QString()) : arg(k), value(v) {}
|
||||
|
||||
QString arg;
|
||||
QString value;
|
||||
};
|
||||
|
||||
QList<Arg> tokenize(QString in) const
|
||||
{
|
||||
int index = 0;
|
||||
const int len = in.count();
|
||||
QChar c, nc;
|
||||
State state = Start;
|
||||
QString key, value;
|
||||
QList<Arg> result;
|
||||
|
||||
for (; index < len; ++index) {
|
||||
c = in.at(index);
|
||||
nc = index < (len - 1) ? in.at(index + 1) : QChar();
|
||||
|
||||
switch (state) {
|
||||
case Start:
|
||||
if (c == QChar('-')) {
|
||||
if (nc == QChar('-')) {
|
||||
state = Key;
|
||||
key.clear();
|
||||
++index;
|
||||
} else {
|
||||
// should we pemit single hyphen arguments?
|
||||
// choosing to fail for now
|
||||
return QList<Arg>();
|
||||
}
|
||||
} else if (c == QChar('#')) {
|
||||
state = Comment;
|
||||
break;
|
||||
} else if (c.isSpace()) {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case Key:
|
||||
if (c == QChar('=')) {
|
||||
state = Value;
|
||||
value.clear();
|
||||
} else if (c.isSpace()) {
|
||||
state = Start;
|
||||
result.append(Arg(key));
|
||||
} else {
|
||||
// could check for illegal charatcers here
|
||||
key.append(c);
|
||||
}
|
||||
break;
|
||||
|
||||
case Value:
|
||||
if (c == QChar('"')) {
|
||||
state = Quoted;
|
||||
} else if (c.isSpace()) {
|
||||
state = Start;
|
||||
result.append(Arg(key, value));
|
||||
} else {
|
||||
value.append(c);
|
||||
}
|
||||
break;
|
||||
|
||||
case Quoted:
|
||||
if (c == QChar('\\')) {
|
||||
// check for escaped double-quote inside quoted value
|
||||
if (nc == QChar('"')) {
|
||||
++index;
|
||||
}
|
||||
} else if (c == QChar('"')) {
|
||||
state = Value;
|
||||
} else {
|
||||
value.append(c);
|
||||
}
|
||||
break;
|
||||
|
||||
case Comment:
|
||||
if ((c == QChar('\n')) || (c == QChar('\r'))) {
|
||||
state = Start;
|
||||
break;
|
||||
} else {
|
||||
// nothing to do, eat comment chars
|
||||
}
|
||||
break;
|
||||
} // of state switch
|
||||
} // of character loop
|
||||
|
||||
// ensure last argument isn't lost
|
||||
if (state == Key) {
|
||||
result.append(Arg(key));
|
||||
} else if (state == Value) {
|
||||
result.append(Arg(key, value));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
enum State {
|
||||
Start = 0,
|
||||
Key,
|
||||
Value,
|
||||
Quoted,
|
||||
Comment
|
||||
};
|
||||
};
|
||||
|
||||
class NaturalEarthDataLoaderThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -333,139 +221,13 @@ private:
|
|||
flightgear::PolyLineList lines;
|
||||
flightgear::SHPParser::parsePolyLines(path, aType, m_parsedLines, areClosed);
|
||||
}
|
||||
|
||||
|
||||
flightgear::PolyLineList m_parsedLines;
|
||||
unsigned int m_lineInsertCount;
|
||||
};
|
||||
|
||||
} // of anonymous namespace
|
||||
|
||||
class AircraftProxyModel : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AircraftProxyModel(QObject* pr) :
|
||||
QSortFilterProxyModel(pr),
|
||||
m_ratingsFilter(true),
|
||||
m_onlyShowInstalled(false)
|
||||
{
|
||||
for (int i=0; i<4; ++i) {
|
||||
m_ratings[i] = 3;
|
||||
}
|
||||
}
|
||||
|
||||
void setRatings(int* ratings)
|
||||
{
|
||||
::memcpy(m_ratings, ratings, sizeof(int) * 4);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void setAircraftFilterString(QString s)
|
||||
{
|
||||
m_filterString = s;
|
||||
|
||||
m_filterProps = new SGPropertyNode;
|
||||
int index = 0;
|
||||
Q_FOREACH(QString term, s.split(' ')) {
|
||||
m_filterProps->getNode("all-of/text", index++, true)->setStringValue(term.toStdString());
|
||||
}
|
||||
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public slots:
|
||||
void setRatingFilterEnabled(bool e)
|
||||
{
|
||||
if (e == m_ratingsFilter) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_ratingsFilter = e;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void setInstalledFilterEnabled(bool e)
|
||||
{
|
||||
if (e == m_onlyShowInstalled) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_onlyShowInstalled = e;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
|
||||
{
|
||||
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||
QVariant v = index.data(AircraftPackageStatusRole);
|
||||
AircraftItemStatus status = static_cast<AircraftItemStatus>(v.toInt());
|
||||
if (status == MessageWidget) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!filterAircraft(index)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_onlyShowInstalled) {
|
||||
QVariant v = index.data(AircraftPackageStatusRole);
|
||||
AircraftItemStatus status = static_cast<AircraftItemStatus>(v.toInt());
|
||||
if (status == PackageNotInstalled) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_onlyShowInstalled && m_ratingsFilter) {
|
||||
for (int i=0; i<4; ++i) {
|
||||
if (m_ratings[i] > index.data(AircraftRatingRole + i).toInt()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
bool filterAircraft(const QModelIndex& sourceIndex) const
|
||||
{
|
||||
if (m_filterString.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
simgear::pkg::PackageRef pkg = sourceIndex.data(AircraftPackageRefRole).value<simgear::pkg::PackageRef>();
|
||||
if (pkg) {
|
||||
return pkg->matches(m_filterProps.ptr());
|
||||
}
|
||||
|
||||
QString baseName = sourceIndex.data(Qt::DisplayRole).toString();
|
||||
if (baseName.contains(m_filterString, Qt::CaseInsensitive)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
QString longDesc = sourceIndex.data(AircraftLongDescriptionRole).toString();
|
||||
if (longDesc.contains(m_filterString, Qt::CaseInsensitive)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const int variantCount = sourceIndex.data(AircraftVariantCountRole).toInt();
|
||||
for (int variant = 0; variant < variantCount; ++variant) {
|
||||
QString desc = sourceIndex.data(AircraftVariantDescriptionRole + variant).toString();
|
||||
if (desc.contains(m_filterString, Qt::CaseInsensitive)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool m_ratingsFilter;
|
||||
bool m_onlyShowInstalled;
|
||||
int m_ratings[4];
|
||||
QString m_filterString;
|
||||
SGPropertyNode_ptr m_filterProps;
|
||||
};
|
||||
|
||||
class NoOfficialHangarMessage : public QWidget
|
||||
{
|
||||
|
@ -576,7 +338,7 @@ private:
|
|||
|
||||
return VISIT_CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
std::string _aircraftId;
|
||||
SGPath _foundPath;
|
||||
};
|
||||
|
@ -1589,7 +1351,7 @@ void QtLauncher::onPopupAircraftHistory()
|
|||
if (nm.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
QAction* act = m.addAction(nm);
|
||||
act->setData(uri);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue