1 #include "PathsDialog.hxx"
2 #include "ui_PathsDialog.h"
10 #include "CatalogListModel.hxx"
11 #include "AddCatalogDialog.hxx"
12 #include "AircraftModel.hxx"
13 #include "QtLauncher_private.hxx"
15 #include <Main/options.hxx>
16 #include <Main/globals.hxx>
17 #include <Network/HTTPClient.hxx>
19 AddOnsPage::AddOnsPage(QWidget *parent, simgear::pkg::RootRef root) :
21 m_ui(new Ui::AddOnsPage),
26 m_catalogsModel = new CatalogListModel(this, m_packageRoot);
27 m_ui->catalogsList->setModel(m_catalogsModel);
29 // enable drag-drop to re-order the paths
30 m_ui->sceneryPathsList->setDragEnabled(true);
31 m_ui->sceneryPathsList->setDragDropMode(QAbstractItemView::InternalMove);
32 m_ui->sceneryPathsList->setDropIndicatorShown(true);
34 m_ui->aircraftPathsList->setDragEnabled(true);
35 m_ui->aircraftPathsList->setDragDropMode(QAbstractItemView::InternalMove);
36 m_ui->aircraftPathsList->setDropIndicatorShown(true);
38 connect(m_ui->addCatalog, &QToolButton::clicked,
39 this, &AddOnsPage::onAddCatalog);
40 connect(m_ui->addDefaultCatalogButton, &QPushButton::clicked,
41 this, &AddOnsPage::onAddDefaultCatalog);
42 connect(m_ui->removeCatalog, &QToolButton::clicked,
43 this, &AddOnsPage::onRemoveCatalog);
45 connect(m_ui->addSceneryPath, &QToolButton::clicked,
46 this, &AddOnsPage::onAddSceneryPath);
47 connect(m_ui->removeSceneryPath, &QToolButton::clicked,
48 this, &AddOnsPage::onRemoveSceneryPath);
50 connect(m_ui->addAircraftPath, &QToolButton::clicked,
51 this, &AddOnsPage::onAddAircraftPath);
52 connect(m_ui->removeAircraftPath, &QToolButton::clicked,
53 this, &AddOnsPage::onRemoveAircraftPath);
55 connect(m_ui->changeDownloadDir, &QPushButton::clicked,
56 this, &AddOnsPage::onChangeDownloadDir);
58 connect(m_ui->clearDownloadDir, &QPushButton::clicked,
59 this, &AddOnsPage::onClearDownloadDir);
61 connect(m_ui->changeDataDir, &QPushButton::clicked,
62 this, &AddOnsPage::onChangeDataDir);
66 QStringList sceneryPaths = settings.value("scenery-paths").toStringList();
67 m_ui->sceneryPathsList->addItems(sceneryPaths);
69 QStringList aircraftPaths = settings.value("aircraft-paths").toStringList();
70 m_ui->aircraftPathsList->addItems(aircraftPaths);
72 QVariant downloadDir = settings.value("download-dir");
73 if (downloadDir.isValid()) {
74 m_downloadDir = downloadDir.toString();
80 AddOnsPage::~AddOnsPage()
85 void AddOnsPage::onAddSceneryPath()
87 QString path = QFileDialog::getExistingDirectory(this, tr("Choose scenery folder"));
88 if (!path.isEmpty()) {
89 m_ui->sceneryPathsList->addItem(path);
93 // work around a Qt OS-X bug - this dialog is ending ordered
94 // behind the main settings dialog (consequence of modal-dialog
95 // showing a modla dialog showing a modial dialog)
99 void AddOnsPage::onRemoveSceneryPath()
101 if (m_ui->sceneryPathsList->currentItem()) {
102 delete m_ui->sceneryPathsList->currentItem();
107 void AddOnsPage::onAddAircraftPath()
109 QString path = QFileDialog::getExistingDirectory(this, tr("Choose aircraft folder"));
110 if (!path.isEmpty()) {
111 // the user might add a directory containing an 'Aircraft' subdir. Let's attempt
112 // to check for that case and handle it gracefully.
115 if (AircraftItemModel::isCandidateAircraftPath(path)) {
116 m_ui->aircraftPathsList->addItem(path);
119 // no aircraft in speciied path, look for Aircraft/ subdir
121 if (d.exists("Aircraft")) {
122 QString p2 = d.filePath("Aircraft");
123 if (AircraftItemModel::isCandidateAircraftPath(p2)) {
124 m_ui->aircraftPathsList->addItem(p2);
132 mb.setText(QString("No aircraft found in the folder '%1' - add anyway?").arg(path));
133 mb.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
134 mb.setDefaultButton(QMessageBox::No);
137 if (mb.result() == QMessageBox::Yes) {
138 m_ui->aircraftPathsList->addItem(path);
144 // work around a Qt OS-X bug - this dialog is ending ordered
145 // behind the main settings dialog (consequence of modal-dialog
146 // showing a modla dialog showing a modial dialog)
150 void AddOnsPage::onRemoveAircraftPath()
152 if (m_ui->aircraftPathsList->currentItem()) {
153 delete m_ui->aircraftPathsList->currentItem();
158 void AddOnsPage::saveAircraftPaths()
163 for (int i=0; i<m_ui->aircraftPathsList->count(); ++i) {
164 paths.append(m_ui->aircraftPathsList->item(i)->text());
167 settings.setValue("aircraft-paths", paths);
170 void AddOnsPage::saveSceneryPaths()
174 for (int i=0; i<m_ui->sceneryPathsList->count(); ++i) {
175 paths.append(m_ui->sceneryPathsList->item(i)->text());
178 settings.setValue("scenery-paths", paths);
180 emit sceneryPathsChanged();
183 void AddOnsPage::onAddCatalog()
185 QScopedPointer<AddCatalogDialog> dlg(new AddCatalogDialog(this, m_packageRoot));
187 if (dlg->result() == QDialog::Accepted) {
188 m_catalogsModel->refresh();
192 void AddOnsPage::onAddDefaultCatalog()
194 addDefaultCatalog(this);
196 m_catalogsModel->refresh();
200 void AddOnsPage::addDefaultCatalog(QWidget* pr)
202 // check it's not a duplicate somehow
203 FGHTTPClient* http = globals->get_subsystem<FGHTTPClient>();
204 if (http->isDefaultCatalogInstalled())
207 QScopedPointer<AddCatalogDialog> dlg(new AddCatalogDialog(pr, globals->packageRoot()));
208 QUrl url(QString::fromStdString(http->getDefaultCatalogUrl()));
209 dlg->setUrlAndDownload(url);
214 void AddOnsPage::onRemoveCatalog()
216 QModelIndex mi = m_ui->catalogsList->currentIndex();
217 FGHTTPClient* http = globals->get_subsystem<FGHTTPClient>();
220 QString s = QString("Remove aircraft hangar '%1'? All installed aircraft from this "
221 "hangar will be removed.");
222 QString pkgId = mi.data(CatalogIdRole).toString();
224 if (pkgId.toStdString() == http->getDefaultCatalogId()) {
225 s = QString("Remove default aircraft hangar? "
226 "This hangar contains all the default aircraft included with FlightGear. "
227 "If you change your mind in the future, click the 'restore' button.");
229 s = s.arg(mi.data(Qt::DisplayRole).toString());
234 mb.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
235 mb.setDefaultButton(QMessageBox::No);
238 if (mb.result() == QMessageBox::Yes) {
239 m_packageRoot->removeCatalogById(pkgId.toStdString());
246 void AddOnsPage::onChangeDownloadDir()
248 QString path = QFileDialog::getExistingDirectory(this,
249 tr("Choose downloads folder"),
251 if (path.isEmpty()) {
252 return; // user cancelled
255 m_downloadDir = path;
259 void AddOnsPage::onClearDownloadDir()
261 // does this need an 'are you sure'?
262 m_downloadDir.clear();
267 void AddOnsPage::setDownloadDir()
270 if (m_downloadDir.isEmpty()) {
271 settings.remove("download-dir");
273 settings.setValue("download-dir", m_downloadDir);
276 if (m_downloadDir.isEmpty()) {
277 flightgear::Options::sharedInstance()->clearOption("download-dir");
279 flightgear::Options::sharedInstance()->setOption("download-dir", m_downloadDir.toStdString());
282 emit downloadDirChanged();
286 void AddOnsPage::onChangeDataDir()
288 QMessageBox mbox(this);
289 mbox.setText(tr("Change the data files used by FlightGear?"));
290 mbox.setInformativeText(tr("FlightGear requires additional files to operate. "
291 "(Also called the base package, or fg-data) "
292 "You can restart FlightGear and choose a "
293 "different data files location, or restore the default setting."));
294 QPushButton* quitButton = mbox.addButton(tr("Restart FlightGear now"), QMessageBox::YesRole);
295 mbox.addButton(QMessageBox::Cancel);
296 mbox.setDefaultButton(QMessageBox::Cancel);
297 mbox.setIconPixmap(QPixmap(":/app-icon-large"));
300 if (mbox.clickedButton() != quitButton) {
306 // set the option to the magic marker value
307 settings.setValue("fg-root", "!ask");
308 } // scope the ensure settings are written nicely
310 QtLauncher::restartTheApp(QStringList());
313 void AddOnsPage::updateUi()
315 QString s = m_downloadDir;
317 s = QString::fromStdString(flightgear::defaultDownloadDir());
318 s.append(tr(" (default)"));
319 m_ui->clearDownloadDir->setEnabled(false);
321 m_ui->clearDownloadDir->setEnabled(true);
324 QString m = tr("Download location: %1").arg(s);
325 m_ui->downloadLocation->setText(m);
329 QString root = settings.value("fg-root").toString();
331 dataLoc = tr("built-in");
336 m_ui->dataLocation->setText(tr("Data location: %1").arg(dataLoc));
339 FGHTTPClient* http = globals->get_subsystem<FGHTTPClient>();
340 m_ui->addDefaultCatalogButton->setEnabled(!http->isDefaultCatalogInstalled());