1 // SetupRootDialog.cxx - part of GUI launcher using Qt5
3 // Written by James Turner, started December 2014.
5 // Copyright (C) 2014 James Turner <zakalawe@mac.com>
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 // General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 #include "SetupRootDialog.hxx"
27 #include <QFileDialog>
28 #include <QDesktopServices>
31 #include <QMessageBox>
37 #include "ui_SetupRootDialog.h"
39 #include <Main/globals.hxx>
40 #include <Main/fg_init.hxx>
41 #include <Main/options.hxx>
42 #include <Include/version.h>
43 #include <Viewer/WindowBuilder.hxx>
45 SetupRootDialog::SetupRootDialog(PromptState prompt) :
49 m_ui.reset(new Ui::SetupRootDialog);
52 connect(m_ui->browseButton, &QPushButton::clicked,
53 this, &SetupRootDialog::onBrowse);
54 connect(m_ui->downloadButton, &QPushButton::clicked,
55 this, &SetupRootDialog::onDownload);
56 connect(m_ui->buttonBox, &QDialogButtonBox::rejected,
57 this, &QDialog::reject);
58 connect(m_ui->useDefaultsButton, &QPushButton::clicked,
59 this, &SetupRootDialog::onUseDefaults);
61 // decide if the 'use defaults' button should be enabled or not
62 bool ok = defaultRootAcceptable();
63 m_ui->useDefaultsButton->setEnabled(ok);
64 m_ui->useDefaultLabel->setEnabled(ok);
66 m_ui->versionLabel->setText(tr("FlightGear version %1").arg(FLIGHTGEAR_VERSION));
67 m_ui->bigIcon->setPixmap(QPixmap(":/app-icon-large"));
71 bool SetupRootDialog::runDialog(bool usingDefaultRoot)
73 SetupRootDialog::PromptState prompt =
74 usingDefaultRoot ? DefaultPathCheckFailed : ExplicitPathCheckFailed;
75 return runDialog(prompt);
78 bool SetupRootDialog::runDialog(PromptState prompt)
80 // avoid double Apple menu and other weirdness if both Qt and OSG
81 // try to initialise various Cocoa structures.
82 flightgear::WindowBuilder::setPoseAsStandaloneApp(false);
84 SetupRootDialog dlg(prompt);
86 if (dlg.result() != QDialog::Accepted) {
93 std::string SetupRootDialog::restoreUserSelectedRoot()
96 QString path = settings.value("fg-root").toString();
98 bool ok = runDialog(ManualChoiceRequested);
100 // run dialog either exit()s or sets fg_root, so this
101 // behaviour is safe and correct.
102 return globals->get_fg_root();
105 if (path.isEmpty()) {
106 return std::string(); // use the default path
109 if (validatePath(path) && validateVersion(path)) {
110 return path.toStdString();
112 // we have an existing path but it's invalid. Let's ask the
113 // user what they want
114 bool ok = runDialog(VersionCheckFailed);
116 // run dialog either exit()s or sets fg_root, so this
117 // behaviour is safe and correct.
118 return globals->get_fg_root();
122 bool SetupRootDialog::validatePath(QString path)
124 // check assorted files exist in the root location, to avoid any chance of
125 // selecting an incomplete base package. This is probably overkill but does
127 QStringList files = QStringList()
130 << "Materials/base/materials-base.xml"
132 << "Timezone/zone.tab";
139 Q_FOREACH(QString s, files) {
148 bool SetupRootDialog::validateVersion(QString path)
150 std::string ver = fgBasePackageVersion(SGPath(path.toStdString()));
151 return (ver == FLIGHTGEAR_VERSION);
154 bool SetupRootDialog::defaultRootAcceptable()
156 std::string r = flightgear::Options::sharedInstance()->platformDefaultRoot();
157 QString defaultRoot = QString::fromStdString(r);
158 return validatePath(defaultRoot) && validateVersion(defaultRoot);
161 SetupRootDialog::~SetupRootDialog()
166 void SetupRootDialog::onBrowse()
168 m_browsedPath = QFileDialog::getExistingDirectory(this,
169 tr("Choose FlightGear data folder"));
170 if (m_browsedPath.isEmpty()) {
174 if (!validatePath(m_browsedPath)) {
175 m_promptState = ChoseInvalidLocation;
180 if (!validateVersion(m_browsedPath)) {
181 m_promptState = ChoseInvalidVersion;
186 globals->set_fg_root(m_browsedPath.toStdString());
189 settings.setValue("fg-root", m_browsedPath);
191 accept(); // we're done
194 void SetupRootDialog::onDownload()
196 QUrl downloadUrl("http://download.flightgear.org/flightgear/Shared/");
197 QDesktopServices::openUrl(downloadUrl);
200 void SetupRootDialog::onUseDefaults()
202 std::string r = flightgear::Options::sharedInstance()->platformDefaultRoot();
203 m_browsedPath = QString::fromStdString(r);
204 globals->set_fg_root(r);
206 settings.remove("fg-root"); // remove any setting
210 void SetupRootDialog::updatePromptText()
213 QString curRoot = QString::fromStdString(globals->get_fg_root());
214 switch (m_promptState) {
215 case DefaultPathCheckFailed:
216 t = tr("This copy of FlightGear does not include the base data files. " \
217 "Please select a suitable folder containing a previously download set of files.");
220 case ExplicitPathCheckFailed:
221 t = tr("The requested location '%1' does not appear to be a valid set of data files for FlightGear").arg(curRoot);
224 case VersionCheckFailed:
226 QString curVer = QString::fromStdString(fgBasePackageVersion(globals->get_fg_root()));
227 t = tr("Detected incompatible version of the data files: version %1 found, but this is FlightGear %2. " \
228 "(At location: '%3') " \
229 "Please install or select a matching set of data files.").arg(curVer).arg(QString::fromLatin1(FLIGHTGEAR_VERSION)).arg(curRoot);
233 case ManualChoiceRequested:
234 t = tr("Please select or download a copy of the FlightGear data files.");
237 case ChoseInvalidLocation:
238 t = tr("The choosen location (%1) does not appear to contain FlightGear data files. Please try another location.").arg(m_browsedPath);
241 case ChoseInvalidVersion:
243 QString curVer = QString::fromStdString(fgBasePackageVersion(m_browsedPath.toStdString()));
244 t = tr("The choosen location (%1) contains files for version %2, but this is FlightGear %3. " \
245 "Please update or try another location").arg(m_browsedPath).arg(curVer).arg(QString::fromLatin1(FLIGHTGEAR_VERSION));
250 m_ui->promptText->setText(t);