2015-03-07 23:52:03 +00:00
|
|
|
// QtLauncher.cxx - GUI launcher dialog using Qt5
|
|
|
|
//
|
|
|
|
// Written by James Turner, started December 2014.
|
|
|
|
//
|
|
|
|
// Copyright (C) 2014 James Turner <zakalawe@mac.com>
|
|
|
|
//
|
|
|
|
// This program is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU General Public License as
|
|
|
|
// published by the Free Software Foundation; either version 2 of the
|
|
|
|
// License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful, but
|
|
|
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
// General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with this program; if not, write to the Free Software
|
|
|
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
2014-12-26 12:20:51 +00:00
|
|
|
#include "QtLauncher.hxx"
|
|
|
|
|
2016-02-02 20:44:46 +00:00
|
|
|
#include <locale.h>
|
|
|
|
|
2014-12-26 12:20:51 +00:00
|
|
|
// Qt
|
|
|
|
#include <QProgressDialog>
|
|
|
|
#include <QDir>
|
|
|
|
#include <QFileInfo>
|
|
|
|
#include <QPixmap>
|
|
|
|
#include <QTimer>
|
|
|
|
#include <QDebug>
|
|
|
|
#include <QCompleter>
|
|
|
|
#include <QListView>
|
|
|
|
#include <QSettings>
|
|
|
|
#include <QUrl>
|
|
|
|
#include <QAction>
|
2015-03-05 17:39:37 +00:00
|
|
|
#include <QDateTime>
|
2015-03-06 18:52:06 +00:00
|
|
|
#include <QApplication>
|
2015-10-16 01:05:17 +00:00
|
|
|
#include <QSpinBox>
|
|
|
|
#include <QDoubleSpinBox>
|
2016-08-08 22:13:57 +00:00
|
|
|
#include <QThread>
|
2017-02-20 00:19:13 +00:00
|
|
|
#include <QProcess>
|
2014-12-26 12:20:51 +00:00
|
|
|
|
|
|
|
// Simgear
|
|
|
|
#include <simgear/timing/timestamp.hxx>
|
|
|
|
#include <simgear/props/props_io.hxx>
|
|
|
|
#include <simgear/structure/exception.hxx>
|
2015-03-10 08:30:55 +00:00
|
|
|
#include <simgear/structure/subsystem_mgr.hxx>
|
2014-12-26 12:20:51 +00:00
|
|
|
#include <simgear/misc/sg_path.hxx>
|
2015-08-03 20:53:56 +00:00
|
|
|
#include <simgear/package/Catalog.hxx>
|
|
|
|
#include <simgear/package/Package.hxx>
|
|
|
|
#include <simgear/package/Install.hxx>
|
2017-01-29 15:16:28 +00:00
|
|
|
#include <simgear/debug/logstream.hxx>
|
2014-12-26 12:20:51 +00:00
|
|
|
|
|
|
|
#include <Main/globals.hxx>
|
2016-07-08 08:36:42 +00:00
|
|
|
#include <Main/fg_props.hxx>
|
2014-12-26 12:20:51 +00:00
|
|
|
#include <Navaids/NavDataCache.hxx>
|
2015-10-16 01:05:17 +00:00
|
|
|
#include <Navaids/navrecord.hxx>
|
2015-11-26 16:48:23 +00:00
|
|
|
#include <Navaids/SHPParser.hxx>
|
2017-01-25 20:41:40 +00:00
|
|
|
#include <Airports/airport.hxx>
|
2015-10-16 01:05:17 +00:00
|
|
|
|
2014-12-26 12:20:51 +00:00
|
|
|
#include <Main/options.hxx>
|
2015-03-10 08:30:55 +00:00
|
|
|
#include <Main/fg_init.hxx>
|
2015-03-06 18:52:06 +00:00
|
|
|
#include <Viewer/WindowBuilder.hxx>
|
2015-03-10 08:30:55 +00:00
|
|
|
#include <Network/HTTPClient.hxx>
|
2014-12-26 12:20:51 +00:00
|
|
|
|
2017-02-20 00:19:13 +00:00
|
|
|
#include "LauncherMainWindow.hxx"
|
2017-01-30 07:00:37 +00:00
|
|
|
|
2014-12-26 12:20:51 +00:00
|
|
|
using namespace flightgear;
|
2015-08-03 20:53:56 +00:00
|
|
|
using namespace simgear::pkg;
|
Split flightgear::initApp() to make it usable even without FGGlobals initialized
- Add an optional argument to flightgear::initApp(): doInitQSettings.
This argument defaults to true, preserving initApp()'s behavior in
this respect. If this argument is set to false, FGGlobals doesn't have
to be initialized.
- New function flightgear::initQSettings(), called by
flightgear::initApp() when its 'doInitQSettings' argument is true.
This allows initializing the QSettings exactly when it is needed.
- New function flightgear::checkKeyboardModifiersForSettingFGRoot().
The code it contains used to be run from initApp(), which is
undesirable because:
1) initApp() is not only called at FG initialization (fgMainInit()),
but also from QtMessageBox(), from QtFileDialog::exec() and twice
from Options::setupRoot(). However, checking the Alt and Shift
modifiers to set 'fg-root' in QSettings to the special value
"!ask" only makes sense in fgMainInit(), not in these other
places.
2) This code relies on the QSettings to be set up, and therefore on
FGGlobals. Thus, freeing initApp() of its dependency on FGGlobals
requires splitting this keyboard modifiers checking code out of
initApp().
2016-12-26 20:45:44 +00:00
|
|
|
using std::string;
|
2014-12-26 12:20:51 +00:00
|
|
|
|
|
|
|
namespace { // anonymous namespace
|
|
|
|
|
|
|
|
void initNavCache()
|
|
|
|
{
|
2015-03-19 17:01:38 +00:00
|
|
|
QString baseLabel = QT_TR_NOOP("Initialising navigation data, this may take several minutes");
|
2015-03-08 00:40:22 +00:00
|
|
|
NavDataCache* cache = NavDataCache::createInstance();
|
2014-12-26 12:20:51 +00:00
|
|
|
if (cache->isRebuildRequired()) {
|
2015-03-19 17:01:38 +00:00
|
|
|
QProgressDialog rebuildProgress(baseLabel,
|
2014-12-26 12:20:51 +00:00
|
|
|
QString() /* cancel text */,
|
2016-04-13 14:15:27 +00:00
|
|
|
0, 100, Q_NULLPTR,
|
|
|
|
Qt::Dialog
|
|
|
|
| Qt::CustomizeWindowHint
|
|
|
|
| Qt::WindowTitleHint
|
|
|
|
| Qt::WindowSystemMenuHint
|
|
|
|
| Qt::MSWindowsFixedSizeDialogHint);
|
2014-12-26 12:20:51 +00:00
|
|
|
rebuildProgress.setWindowModality(Qt::WindowModal);
|
|
|
|
rebuildProgress.show();
|
|
|
|
|
2015-03-19 17:01:38 +00:00
|
|
|
NavDataCache::RebuildPhase phase = cache->rebuild();
|
|
|
|
|
|
|
|
while (phase != NavDataCache::REBUILD_DONE) {
|
2014-12-26 12:20:51 +00:00
|
|
|
// sleep to give the rebuild thread more time
|
|
|
|
SGTimeStamp::sleepForMSec(50);
|
2015-03-19 17:01:38 +00:00
|
|
|
phase = cache->rebuild();
|
2015-10-16 01:05:17 +00:00
|
|
|
|
2015-03-19 17:01:38 +00:00
|
|
|
switch (phase) {
|
2016-10-19 11:01:35 +00:00
|
|
|
case NavDataCache::REBUILD_READING_APT_DAT_FILES:
|
|
|
|
rebuildProgress.setLabelText(QT_TR_NOOP("Reading airport data"));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NavDataCache::REBUILD_LOADING_AIRPORTS:
|
|
|
|
rebuildProgress.setLabelText(QT_TR_NOOP("Loading airports"));
|
2015-03-19 17:01:38 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case NavDataCache::REBUILD_FIXES:
|
|
|
|
rebuildProgress.setLabelText(QT_TR_NOOP("Loading waypoint data"));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NavDataCache::REBUILD_NAVAIDS:
|
|
|
|
rebuildProgress.setLabelText(QT_TR_NOOP("Loading navigation data"));
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case NavDataCache::REBUILD_POIS:
|
|
|
|
rebuildProgress.setLabelText(QT_TR_NOOP("Loading point-of-interest data"));
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
rebuildProgress.setLabelText(baseLabel);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (phase == NavDataCache::REBUILD_UNKNOWN) {
|
|
|
|
rebuildProgress.setValue(0);
|
|
|
|
rebuildProgress.setMaximum(0);
|
|
|
|
} else {
|
|
|
|
rebuildProgress.setValue(cache->rebuildPhaseCompletionPercentage());
|
|
|
|
rebuildProgress.setMaximum(100);
|
|
|
|
}
|
|
|
|
|
2014-12-26 12:20:51 +00:00
|
|
|
QCoreApplication::processEvents();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-08 22:13:57 +00:00
|
|
|
class NaturalEarthDataLoaderThread : public QThread
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
|
2016-08-09 08:38:54 +00:00
|
|
|
NaturalEarthDataLoaderThread() :
|
|
|
|
m_lineInsertCount(0)
|
2016-08-08 22:13:57 +00:00
|
|
|
{
|
|
|
|
connect(this, &QThread::finished, this, &NaturalEarthDataLoaderThread::onFinished);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
virtual void run() Q_DECL_OVERRIDE
|
|
|
|
{
|
|
|
|
SGTimeStamp st;
|
|
|
|
st.stamp();
|
|
|
|
|
|
|
|
loadNaturalEarthFile("ne_10m_coastline.shp", flightgear::PolyLine::COASTLINE, false);
|
|
|
|
loadNaturalEarthFile("ne_10m_rivers_lake_centerlines.shp", flightgear::PolyLine::RIVER, false);
|
|
|
|
loadNaturalEarthFile("ne_10m_lakes.shp", flightgear::PolyLine::LAKE, true);
|
|
|
|
|
|
|
|
qDebug() << "load basic data took" << st.elapsedMSec();
|
|
|
|
|
|
|
|
st.stamp();
|
|
|
|
loadNaturalEarthFile("ne_10m_urban_areas.shp", flightgear::PolyLine::URBAN, true);
|
|
|
|
|
|
|
|
qDebug() << "loading urban areas took:" << st.elapsedMSec();
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2016-08-15 22:10:06 +00:00
|
|
|
Q_SLOT void onFinished()
|
2016-08-08 22:13:57 +00:00
|
|
|
{
|
2016-08-09 08:38:54 +00:00
|
|
|
flightgear::PolyLineList::const_iterator begin = m_parsedLines.begin() + m_lineInsertCount;
|
2016-08-12 09:48:34 +00:00
|
|
|
unsigned int numToAdd = std::min<unsigned long>(1000UL, m_parsedLines.size() - m_lineInsertCount);
|
2016-08-09 08:38:54 +00:00
|
|
|
flightgear::PolyLineList::const_iterator end = begin + numToAdd;
|
|
|
|
flightgear::PolyLine::bulkAddToSpatialIndex(begin, end);
|
|
|
|
|
|
|
|
if (end == m_parsedLines.end()) {
|
|
|
|
deleteLater(); // commit suicide
|
|
|
|
} else {
|
|
|
|
m_lineInsertCount += 1000;
|
2016-08-11 21:32:29 +00:00
|
|
|
QTimer::singleShot(50, this, SLOT(onFinished()));
|
2016-08-09 08:38:54 +00:00
|
|
|
}
|
2016-08-08 22:13:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void loadNaturalEarthFile(const std::string& aFileName,
|
|
|
|
flightgear::PolyLine::Type aType,
|
|
|
|
bool areClosed)
|
|
|
|
{
|
|
|
|
SGPath path(globals->get_fg_root());
|
|
|
|
path.append( "Geodata" );
|
|
|
|
path.append(aFileName);
|
|
|
|
if (!path.exists())
|
|
|
|
return; // silently fail for now
|
|
|
|
|
|
|
|
flightgear::PolyLineList lines;
|
|
|
|
flightgear::SHPParser::parsePolyLines(path, aType, m_parsedLines, areClosed);
|
|
|
|
}
|
2017-02-19 22:59:39 +00:00
|
|
|
|
2016-08-08 22:13:57 +00:00
|
|
|
flightgear::PolyLineList m_parsedLines;
|
2016-08-09 08:38:54 +00:00
|
|
|
unsigned int m_lineInsertCount;
|
2016-08-08 22:13:57 +00:00
|
|
|
};
|
|
|
|
|
2014-12-26 12:20:51 +00:00
|
|
|
} // of anonymous namespace
|
|
|
|
|
2015-10-16 01:05:17 +00:00
|
|
|
static void initQtResources()
|
|
|
|
{
|
|
|
|
Q_INIT_RESOURCE(resources);
|
|
|
|
}
|
|
|
|
|
2017-02-19 22:59:39 +00:00
|
|
|
|
2017-01-25 20:41:40 +00:00
|
|
|
|
2017-01-29 15:16:28 +00:00
|
|
|
static void simgearMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
|
|
|
|
{
|
|
|
|
sgDebugPriority mappedPriority = SG_WARN;
|
|
|
|
switch (type) {
|
|
|
|
case QtDebugMsg: mappedPriority = SG_DEBUG; break;
|
2017-02-01 16:36:48 +00:00
|
|
|
#if QT_VERSION >= 0x050500
|
2017-01-29 15:16:28 +00:00
|
|
|
case QtInfoMsg: mappedPriority = SG_INFO; break;
|
2017-02-01 16:36:48 +00:00
|
|
|
#endif
|
2017-01-29 15:16:28 +00:00
|
|
|
case QtWarningMsg: mappedPriority = SG_WARN; break;
|
|
|
|
case QtCriticalMsg: mappedPriority = SG_ALERT; break;
|
|
|
|
case QtFatalMsg: mappedPriority = SG_POPUP; break;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char* nullFile = "";
|
|
|
|
const char* file = context.file ? context.file : nullFile;
|
|
|
|
sglog().log(SG_GUI, mappedPriority, file, context.line, msg.toStdString());
|
|
|
|
if (type == QtFatalMsg) {
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-16 01:05:17 +00:00
|
|
|
namespace flightgear
|
|
|
|
{
|
|
|
|
|
Split flightgear::initApp() to make it usable even without FGGlobals initialized
- Add an optional argument to flightgear::initApp(): doInitQSettings.
This argument defaults to true, preserving initApp()'s behavior in
this respect. If this argument is set to false, FGGlobals doesn't have
to be initialized.
- New function flightgear::initQSettings(), called by
flightgear::initApp() when its 'doInitQSettings' argument is true.
This allows initializing the QSettings exactly when it is needed.
- New function flightgear::checkKeyboardModifiersForSettingFGRoot().
The code it contains used to be run from initApp(), which is
undesirable because:
1) initApp() is not only called at FG initialization (fgMainInit()),
but also from QtMessageBox(), from QtFileDialog::exec() and twice
from Options::setupRoot(). However, checking the Alt and Shift
modifiers to set 'fg-root' in QSettings to the special value
"!ask" only makes sense in fgMainInit(), not in these other
places.
2) This code relies on the QSettings to be set up, and therefore on
FGGlobals. Thus, freeing initApp() of its dependency on FGGlobals
requires splitting this keyboard modifiers checking code out of
initApp().
2016-12-26 20:45:44 +00:00
|
|
|
// Only requires FGGlobals to be initialized if 'doInitQSettings' is true.
|
|
|
|
// Safe to call several times.
|
|
|
|
void initApp(int& argc, char** argv, bool doInitQSettings)
|
2015-10-16 01:05:17 +00:00
|
|
|
{
|
|
|
|
static bool qtInitDone = false;
|
2015-11-26 16:49:55 +00:00
|
|
|
static int s_argc;
|
|
|
|
|
2015-10-16 01:05:17 +00:00
|
|
|
if (!qtInitDone) {
|
|
|
|
qtInitDone = true;
|
2016-02-02 20:44:46 +00:00
|
|
|
|
|
|
|
sglog().setLogLevels( SG_ALL, SG_INFO );
|
|
|
|
initQtResources(); // can't be called from a namespace
|
|
|
|
|
2015-11-26 16:49:55 +00:00
|
|
|
s_argc = argc; // QApplication only stores a reference to argc,
|
|
|
|
// and may crash if it is freed
|
|
|
|
// http://doc.qt.io/qt-5/qguiapplication.html#QGuiApplication
|
2015-10-16 01:05:17 +00:00
|
|
|
|
2017-01-29 15:16:28 +00:00
|
|
|
// log to simgear instead of the console from Qt, so we go to
|
|
|
|
// whichever log locations SimGear has configured
|
|
|
|
qInstallMessageHandler(simgearMessageOutput);
|
|
|
|
|
2015-11-26 16:49:55 +00:00
|
|
|
QApplication* app = new QApplication(s_argc, argv);
|
2015-10-16 01:05:17 +00:00
|
|
|
app->setOrganizationName("FlightGear");
|
|
|
|
app->setApplicationName("FlightGear");
|
|
|
|
app->setOrganizationDomain("flightgear.org");
|
|
|
|
|
2016-02-02 20:44:46 +00:00
|
|
|
// reset numeric / collation locales as described at:
|
|
|
|
// http://doc.qt.io/qt-5/qcoreapplication.html#details
|
|
|
|
::setlocale(LC_NUMERIC, "C");
|
|
|
|
::setlocale(LC_COLLATE, "C");
|
Split flightgear::initApp() to make it usable even without FGGlobals initialized
- Add an optional argument to flightgear::initApp(): doInitQSettings.
This argument defaults to true, preserving initApp()'s behavior in
this respect. If this argument is set to false, FGGlobals doesn't have
to be initialized.
- New function flightgear::initQSettings(), called by
flightgear::initApp() when its 'doInitQSettings' argument is true.
This allows initializing the QSettings exactly when it is needed.
- New function flightgear::checkKeyboardModifiersForSettingFGRoot().
The code it contains used to be run from initApp(), which is
undesirable because:
1) initApp() is not only called at FG initialization (fgMainInit()),
but also from QtMessageBox(), from QtFileDialog::exec() and twice
from Options::setupRoot(). However, checking the Alt and Shift
modifiers to set 'fg-root' in QSettings to the special value
"!ask" only makes sense in fgMainInit(), not in these other
places.
2) This code relies on the QSettings to be set up, and therefore on
FGGlobals. Thus, freeing initApp() of its dependency on FGGlobals
requires splitting this keyboard modifiers checking code out of
initApp().
2016-12-26 20:45:44 +00:00
|
|
|
}
|
2016-02-02 20:44:46 +00:00
|
|
|
|
Split flightgear::initApp() to make it usable even without FGGlobals initialized
- Add an optional argument to flightgear::initApp(): doInitQSettings.
This argument defaults to true, preserving initApp()'s behavior in
this respect. If this argument is set to false, FGGlobals doesn't have
to be initialized.
- New function flightgear::initQSettings(), called by
flightgear::initApp() when its 'doInitQSettings' argument is true.
This allows initializing the QSettings exactly when it is needed.
- New function flightgear::checkKeyboardModifiersForSettingFGRoot().
The code it contains used to be run from initApp(), which is
undesirable because:
1) initApp() is not only called at FG initialization (fgMainInit()),
but also from QtMessageBox(), from QtFileDialog::exec() and twice
from Options::setupRoot(). However, checking the Alt and Shift
modifiers to set 'fg-root' in QSettings to the special value
"!ask" only makes sense in fgMainInit(), not in these other
places.
2) This code relies on the QSettings to be set up, and therefore on
FGGlobals. Thus, freeing initApp() of its dependency on FGGlobals
requires splitting this keyboard modifiers checking code out of
initApp().
2016-12-26 20:45:44 +00:00
|
|
|
if (doInitQSettings) {
|
|
|
|
initQSettings();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Requires FGGlobals to be initialized. Safe to call several times.
|
|
|
|
void initQSettings()
|
|
|
|
{
|
|
|
|
static bool qSettingsInitDone = false;
|
|
|
|
|
|
|
|
if (!qSettingsInitDone) {
|
|
|
|
qSettingsInitDone = true;
|
|
|
|
string fgHome = globals->get_fg_home().utf8Str();
|
|
|
|
|
|
|
|
QSettings::setDefaultFormat(QSettings::IniFormat);
|
|
|
|
QSettings::setPath(QSettings::IniFormat, QSettings::UserScope,
|
|
|
|
QString::fromStdString(fgHome));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool checkKeyboardModifiersForSettingFGRoot()
|
|
|
|
{
|
|
|
|
initQSettings();
|
|
|
|
|
|
|
|
Qt::KeyboardModifiers mods = qApp->queryKeyboardModifiers();
|
|
|
|
if (mods & (Qt::AltModifier | Qt::ShiftModifier)) {
|
|
|
|
qWarning() << "Alt/shift pressed during launch";
|
|
|
|
QSettings settings;
|
|
|
|
settings.setValue("fg-root", "!ask");
|
|
|
|
return true;
|
2015-10-16 01:05:17 +00:00
|
|
|
}
|
Split flightgear::initApp() to make it usable even without FGGlobals initialized
- Add an optional argument to flightgear::initApp(): doInitQSettings.
This argument defaults to true, preserving initApp()'s behavior in
this respect. If this argument is set to false, FGGlobals doesn't have
to be initialized.
- New function flightgear::initQSettings(), called by
flightgear::initApp() when its 'doInitQSettings' argument is true.
This allows initializing the QSettings exactly when it is needed.
- New function flightgear::checkKeyboardModifiersForSettingFGRoot().
The code it contains used to be run from initApp(), which is
undesirable because:
1) initApp() is not only called at FG initialization (fgMainInit()),
but also from QtMessageBox(), from QtFileDialog::exec() and twice
from Options::setupRoot(). However, checking the Alt and Shift
modifiers to set 'fg-root' in QSettings to the special value
"!ask" only makes sense in fgMainInit(), not in these other
places.
2) This code relies on the QSettings to be set up, and therefore on
FGGlobals. Thus, freeing initApp() of its dependency on FGGlobals
requires splitting this keyboard modifiers checking code out of
initApp().
2016-12-26 20:45:44 +00:00
|
|
|
|
|
|
|
return false;
|
2015-10-16 01:05:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-02-20 00:19:13 +00:00
|
|
|
void restartTheApp()
|
2014-12-26 12:20:51 +00:00
|
|
|
{
|
2017-02-20 00:19:13 +00:00
|
|
|
QStringList fgArgs;
|
2014-12-26 12:20:51 +00:00
|
|
|
|
2017-02-20 00:19:13 +00:00
|
|
|
// Spawn a new instance of myApplication:
|
|
|
|
QProcess proc;
|
|
|
|
QStringList args;
|
2014-12-26 12:20:51 +00:00
|
|
|
|
2017-02-20 00:19:13 +00:00
|
|
|
#if defined(Q_OS_MAC)
|
|
|
|
QDir dir(qApp->applicationDirPath()); // returns the 'MacOS' dir
|
|
|
|
dir.cdUp(); // up to 'contents' dir
|
|
|
|
dir.cdUp(); // up to .app dir
|
|
|
|
// see 'man open' for details, but '-n' ensures we launch a new instance,
|
|
|
|
// and we want to pass remaining arguments to us, not open.
|
|
|
|
args << "-n" << dir.absolutePath() << "--args" << "--launcher" << fgArgs;
|
|
|
|
qDebug() << "args" << args;
|
|
|
|
proc.startDetached("open", args);
|
|
|
|
#else
|
|
|
|
args << "--launcher" << fgArgs;
|
|
|
|
proc.startDetached(qApp->applicationFilePath(), args);
|
2017-01-30 07:00:37 +00:00
|
|
|
#endif
|
2017-02-20 00:19:13 +00:00
|
|
|
qApp->exit(-1);
|
2014-12-26 12:20:51 +00:00
|
|
|
}
|
|
|
|
|
2015-10-16 01:05:17 +00:00
|
|
|
|
2017-02-20 00:19:13 +00:00
|
|
|
void launcherSetSceneryPaths()
|
2016-01-10 22:38:01 +00:00
|
|
|
{
|
|
|
|
globals->clear_fg_scenery();
|
|
|
|
|
2017-02-20 00:19:13 +00:00
|
|
|
// mimic what options.cxx does, so we can find airport data for parking
|
2016-01-10 22:38:01 +00:00
|
|
|
// positions
|
|
|
|
QSettings settings;
|
|
|
|
// append explicit scenery paths
|
|
|
|
Q_FOREACH(QString path, settings.value("scenery-paths").toStringList()) {
|
|
|
|
globals->append_fg_scenery(path.toStdString());
|
|
|
|
}
|
|
|
|
|
|
|
|
// append the TerraSync path
|
|
|
|
QString downloadDir = settings.value("download-dir").toString();
|
|
|
|
if (downloadDir.isEmpty()) {
|
2016-06-23 13:26:34 +00:00
|
|
|
downloadDir = QString::fromStdString(flightgear::defaultDownloadDir().utf8Str());
|
2016-01-10 22:38:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SGPath terraSyncDir(downloadDir.toStdString());
|
|
|
|
terraSyncDir.append("TerraSync");
|
|
|
|
if (terraSyncDir.exists()) {
|
2016-06-21 11:29:04 +00:00
|
|
|
globals->append_fg_scenery(terraSyncDir);
|
2016-01-10 22:38:01 +00:00
|
|
|
}
|
|
|
|
|
2016-08-19 11:12:02 +00:00
|
|
|
// add the installation path since it contains default airport data,
|
|
|
|
// if terrasync is disabled or on first-launch
|
|
|
|
globals->append_fg_scenery(globals->get_fg_root() / "Scenery");
|
|
|
|
|
2016-01-10 22:38:01 +00:00
|
|
|
}
|
|
|
|
|
2017-02-20 00:19:13 +00:00
|
|
|
bool runLauncherDialog()
|
2015-10-16 01:05:17 +00:00
|
|
|
{
|
2017-02-20 00:19:13 +00:00
|
|
|
// Used for NavDataCache initialization: needed to find the apt.dat files
|
|
|
|
launcherSetSceneryPaths();
|
|
|
|
// startup the nav-cache now. This pre-empts normal startup of
|
|
|
|
// the cache, but no harm done. (Providing scenery paths are consistent)
|
2017-01-26 00:31:41 +00:00
|
|
|
|
2017-02-20 00:19:13 +00:00
|
|
|
initNavCache();
|
2014-12-26 12:20:51 +00:00
|
|
|
|
|
|
|
QSettings settings;
|
2017-02-20 00:19:13 +00:00
|
|
|
QString downloadDir = settings.value("download-dir").toString();
|
|
|
|
if (!downloadDir.isEmpty()) {
|
|
|
|
flightgear::Options::sharedInstance()->setOption("download-dir", downloadDir.toStdString());
|
2016-11-07 11:54:38 +00:00
|
|
|
}
|
2014-12-26 12:20:51 +00:00
|
|
|
|
2017-02-20 00:19:13 +00:00
|
|
|
fgInitPackageRoot();
|
2016-01-10 18:56:46 +00:00
|
|
|
|
2017-02-20 00:19:13 +00:00
|
|
|
// startup the HTTP system now since packages needs it
|
|
|
|
FGHTTPClient* http = globals->add_new_subsystem<FGHTTPClient>();
|
2014-12-26 12:20:51 +00:00
|
|
|
|
2017-02-20 00:19:13 +00:00
|
|
|
// we guard against re-init in the global phase; bind and postinit
|
|
|
|
// will happen as normal
|
|
|
|
http->init();
|
2014-12-26 12:20:51 +00:00
|
|
|
|
2017-02-20 00:19:13 +00:00
|
|
|
NaturalEarthDataLoaderThread* naturalEarthLoader = new NaturalEarthDataLoaderThread;
|
|
|
|
naturalEarthLoader->start();
|
2016-07-08 08:36:42 +00:00
|
|
|
|
2017-02-20 00:19:13 +00:00
|
|
|
// avoid double Apple menu and other weirdness if both Qt and OSG
|
|
|
|
// try to initialise various Cocoa structures.
|
|
|
|
flightgear::WindowBuilder::setPoseAsStandaloneApp(false);
|
2014-12-26 12:20:51 +00:00
|
|
|
|
2017-02-20 00:19:13 +00:00
|
|
|
LauncherMainWindow dlg;
|
|
|
|
dlg.show();
|
2016-01-10 19:47:57 +00:00
|
|
|
|
2017-02-20 00:19:13 +00:00
|
|
|
int appResult = qApp->exec();
|
|
|
|
if (appResult <= 0) {
|
|
|
|
return false; // quit
|
2016-01-10 19:47:57 +00:00
|
|
|
}
|
2015-10-25 00:40:41 +00:00
|
|
|
|
2017-02-20 00:19:13 +00:00
|
|
|
// don't set scenery paths twice
|
|
|
|
globals->clear_fg_scenery();
|
2015-11-03 21:28:36 +00:00
|
|
|
|
2017-02-20 00:19:13 +00:00
|
|
|
return true;
|
2014-12-26 12:20:51 +00:00
|
|
|
}
|
|
|
|
|
2017-02-20 00:19:13 +00:00
|
|
|
bool runInAppLauncherDialog()
|
2014-12-26 12:20:51 +00:00
|
|
|
{
|
2017-02-20 00:19:13 +00:00
|
|
|
LauncherMainWindow dlg;
|
|
|
|
bool accepted = dlg.execInApp();
|
|
|
|
if (!accepted) {
|
|
|
|
return false;
|
2014-12-26 12:20:51 +00:00
|
|
|
}
|
|
|
|
|
2017-02-20 00:19:13 +00:00
|
|
|
return true;
|
2016-02-24 19:50:37 +00:00
|
|
|
}
|
|
|
|
|
2017-02-20 00:19:13 +00:00
|
|
|
} // of namespace flightgear
|
2016-01-17 19:10:22 +00:00
|
|
|
|
2015-10-16 01:05:17 +00:00
|
|
|
#include "QtLauncher.moc"
|