In-app launcher for Mac, based on Qt5.
The old Mac launcher doesn’t work on Yosemite, add a tiny Qt-based launcher inside the main process (no need to fork / exec) which runs before the OSG window is created. Will be merged for 3.4, hopefully with no impact on other platforms.
This commit is contained in:
parent
0a28e95107
commit
78e8f53312
23 changed files with 2784 additions and 43 deletions
|
@ -277,6 +277,16 @@ endif (USE_DBUS)
|
|||
# Sqlite always depends on the threading lib
|
||||
list(APPEND SQLITE3_LIBRARY ${CMAKE_THREAD_LIBS_INIT})
|
||||
|
||||
##############################################################################
|
||||
## Qt5 setup setup
|
||||
|
||||
find_package(Qt5 5.1 COMPONENTS Widgets)
|
||||
if (Qt5Widgets_FOUND)
|
||||
message(STATUS "Will enable Qt launcher GUI")
|
||||
set(HAVE_QT 1)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
endif()
|
||||
|
||||
##############################################################################
|
||||
|
||||
find_package(PLIB REQUIRED puaux pu js fnt)
|
||||
|
|
264
src/GUI/AirportDiagram.cxx
Normal file
264
src/GUI/AirportDiagram.cxx
Normal file
|
@ -0,0 +1,264 @@
|
|||
#include "AirportDiagram.hxx"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QDebug>
|
||||
|
||||
#include <Airports/airport.hxx>
|
||||
#include <Airports/runways.hxx>
|
||||
#include <Airports/parking.hxx>
|
||||
#include <Airports/pavement.hxx>
|
||||
|
||||
/* equatorial and polar earth radius */
|
||||
const float rec = 6378137; // earth radius, equator (?)
|
||||
const float rpol = 6356752.314f; // earth radius, polar (?)
|
||||
|
||||
//Returns Earth radius at a given latitude (Ellipsoide equation with two equal axis)
|
||||
static float earth_radius_lat( float lat )
|
||||
{
|
||||
double a = cos(lat)/rec;
|
||||
double b = sin(lat)/rpol;
|
||||
return 1.0f / sqrt( a * a + b * b );
|
||||
}
|
||||
|
||||
|
||||
AirportDiagram::AirportDiagram(QWidget* pr) :
|
||||
QWidget(pr)
|
||||
{
|
||||
setSizePolicy(QSizePolicy::MinimumExpanding,
|
||||
QSizePolicy::MinimumExpanding);
|
||||
setMinimumSize(100, 100);
|
||||
}
|
||||
|
||||
void AirportDiagram::setAirport(FGAirportRef apt)
|
||||
{
|
||||
m_airport = apt;
|
||||
m_projectionCenter = apt ? apt->geod() : SGGeod();
|
||||
m_scale = 1.0;
|
||||
m_bounds = QRectF(); // clear
|
||||
m_runways.clear();
|
||||
|
||||
if (apt) {
|
||||
buildTaxiways();
|
||||
buildPavements();
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void AirportDiagram::addRunway(FGRunwayRef rwy)
|
||||
{
|
||||
Q_FOREACH(RunwayData rd, m_runways) {
|
||||
if (rd.runway == rwy->reciprocalRunway()) {
|
||||
return; // only add one end of reciprocal runways
|
||||
}
|
||||
}
|
||||
|
||||
QPointF p1 = project(rwy->geod()),
|
||||
p2 = project(rwy->end());
|
||||
extendBounds(p1);
|
||||
extendBounds(p2);
|
||||
|
||||
RunwayData r;
|
||||
r.p1 = p1;
|
||||
r.p2 = p2;
|
||||
r.widthM = qRound(rwy->widthM());
|
||||
r.runway = rwy;
|
||||
m_runways.append(r);
|
||||
update();
|
||||
}
|
||||
|
||||
void AirportDiagram::addParking(FGParking* park)
|
||||
{
|
||||
QPointF p = project(park->geod());
|
||||
extendBounds(p);
|
||||
update();
|
||||
}
|
||||
|
||||
void AirportDiagram::paintEvent(QPaintEvent* pe)
|
||||
{
|
||||
QPainter p(this);
|
||||
p.fillRect(rect(), QColor(0x3f, 0x3f, 0x3f));
|
||||
|
||||
// fit bounds within our available space, allowing for a margin
|
||||
const int MARGIN = 32; // pixels
|
||||
double ratioInX = (width() - MARGIN * 2) / m_bounds.width();
|
||||
double ratioInY = (height() - MARGIN * 2) / m_bounds.height();
|
||||
double scale = std::min(ratioInX, ratioInY);
|
||||
|
||||
QTransform t;
|
||||
t.translate(width() / 2, height() / 2); // center projection origin in the widget
|
||||
t.scale(scale, scale);
|
||||
// center the bounding box (may not be at the origin)
|
||||
t.translate(-m_bounds.center().x(), -m_bounds.center().y());
|
||||
p.setTransform(t);
|
||||
|
||||
// pavements
|
||||
QBrush brush(QColor(0x9f, 0x9f, 0x9f));
|
||||
Q_FOREACH(const QPainterPath& path, m_pavements) {
|
||||
p.drawPath(path);
|
||||
}
|
||||
|
||||
// taxiways
|
||||
Q_FOREACH(const TaxiwayData& t, m_taxiways) {
|
||||
QPen pen(QColor(0x9f, 0x9f, 0x9f));
|
||||
pen.setWidth(t.widthM);
|
||||
p.setPen(pen);
|
||||
p.drawLine(t.p1, t.p2);
|
||||
}
|
||||
|
||||
// runways
|
||||
QPen pen(Qt::magenta);
|
||||
QFont f;
|
||||
f.setPixelSize(14);
|
||||
p.setFont(f);
|
||||
|
||||
Q_FOREACH(const RunwayData& r, m_runways) {
|
||||
p.setTransform(t);
|
||||
|
||||
pen.setWidth(r.widthM);
|
||||
p.setPen(pen);
|
||||
p.drawLine(r.p1, r.p2);
|
||||
|
||||
// draw idents
|
||||
QString ident = QString::fromStdString(r.runway->ident());
|
||||
|
||||
p.translate(r.p1);
|
||||
p.rotate(r.runway->headingDeg());
|
||||
// invert scaling factor so we can use screen pixel sizes here
|
||||
p.scale(1.0 / scale, 1.0/ scale);
|
||||
|
||||
p.drawText(QRect(-100, 5, 200, 200), ident, Qt::AlignHCenter | Qt::AlignTop);
|
||||
|
||||
FGRunway* recip = r.runway->reciprocalRunway();
|
||||
QString recipIdent = QString::fromStdString(recip->ident());
|
||||
|
||||
p.setTransform(t);
|
||||
p.translate(r.p2);
|
||||
p.rotate(recip->headingDeg());
|
||||
p.scale(1.0 / scale, 1.0/ scale);
|
||||
|
||||
p.drawText(QRect(-100, 5, 200, 200), recipIdent, Qt::AlignHCenter | Qt::AlignTop);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AirportDiagram::extendBounds(const QPointF& p)
|
||||
{
|
||||
if (p.x() < m_bounds.left()) {
|
||||
m_bounds.setLeft(p.x());
|
||||
} else if (p.x() > m_bounds.right()) {
|
||||
m_bounds.setRight(p.x());
|
||||
}
|
||||
|
||||
if (p.y() < m_bounds.top()) {
|
||||
m_bounds.setTop(p.y());
|
||||
} else if (p.y() > m_bounds.bottom()) {
|
||||
m_bounds.setBottom(p.y());
|
||||
}
|
||||
}
|
||||
|
||||
QPointF AirportDiagram::project(const SGGeod& geod) const
|
||||
{
|
||||
double r = earth_radius_lat(geod.getLatitudeRad());
|
||||
double ref_lat = m_projectionCenter.getLatitudeRad(),
|
||||
ref_lon = m_projectionCenter.getLongitudeRad(),
|
||||
lat = geod.getLatitudeRad(),
|
||||
lon = geod.getLongitudeRad(),
|
||||
lonDiff = lon - ref_lon;
|
||||
|
||||
double c = acos( sin(ref_lat) * sin(lat) + cos(ref_lat) * cos(lat) * cos(lonDiff) );
|
||||
if (c == 0.0) {
|
||||
// angular distance from center is 0
|
||||
return QPointF(0.0, 0.0);
|
||||
}
|
||||
|
||||
double k = c / sin(c);
|
||||
double x, y;
|
||||
if (ref_lat == (90 * SG_DEGREES_TO_RADIANS))
|
||||
{
|
||||
x = (SGD_PI / 2 - lat) * sin(lonDiff);
|
||||
y = -(SGD_PI / 2 - lat) * cos(lonDiff);
|
||||
}
|
||||
else if (ref_lat == -(90 * SG_DEGREES_TO_RADIANS))
|
||||
{
|
||||
x = (SGD_PI / 2 + lat) * sin(lonDiff);
|
||||
y = (SGD_PI / 2 + lat) * cos(lonDiff);
|
||||
}
|
||||
else
|
||||
{
|
||||
x = k * cos(lat) * sin(lonDiff);
|
||||
y = k * ( cos(ref_lat) * sin(lat) - sin(ref_lat) * cos(lat) * cos(lonDiff) );
|
||||
}
|
||||
|
||||
return QPointF(x, -y) * r * m_scale;
|
||||
}
|
||||
|
||||
void AirportDiagram::buildTaxiways()
|
||||
{
|
||||
m_taxiways.clear();
|
||||
for (unsigned int tIndex=0; tIndex < m_airport->numTaxiways(); ++tIndex) {
|
||||
FGTaxiwayRef tx = m_airport->getTaxiwayByIndex(tIndex);
|
||||
|
||||
TaxiwayData td;
|
||||
td.p1 = project(tx->geod());
|
||||
td.p2 = project(tx->pointOnCenterline(tx->lengthM()));
|
||||
extendBounds(td.p1);
|
||||
extendBounds(td.p2);
|
||||
td.widthM = tx->widthM();
|
||||
m_taxiways.append(td);
|
||||
}
|
||||
}
|
||||
|
||||
void AirportDiagram::buildPavements()
|
||||
{
|
||||
m_pavements.clear();
|
||||
for (unsigned int pIndex=0; pIndex < m_airport->numPavements(); ++pIndex) {
|
||||
FGPavementRef pave = m_airport->getPavementByIndex(pIndex);
|
||||
if (pave->getNodeList().empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QPainterPath pp;
|
||||
QPointF startPoint;
|
||||
bool closed = true;
|
||||
QPointF p0 = project(pave->getNodeList().front()->mPos);
|
||||
|
||||
FGPavement::NodeList::const_iterator it;
|
||||
for (it = pave->getNodeList().begin(); it != pave->getNodeList().end(); ) {
|
||||
const FGPavement::BezierNode *bn = dynamic_cast<const FGPavement::BezierNode *>(it->get());
|
||||
bool close = (*it)->mClose;
|
||||
|
||||
// increment iterator so we can look at the next point
|
||||
++it;
|
||||
QPointF nextPoint = (it == pave->getNodeList().end()) ? startPoint : project((*it)->mPos);
|
||||
|
||||
if (bn) {
|
||||
QPointF control = project(bn->mControl);
|
||||
QPointF endPoint = close ? startPoint : nextPoint;
|
||||
pp.quadTo(control, endPoint);
|
||||
} else {
|
||||
// straight line segment
|
||||
if (closed) {
|
||||
pp.moveTo(p0);
|
||||
closed = false;
|
||||
startPoint = p0;
|
||||
} else
|
||||
pp.lineTo(p0);
|
||||
}
|
||||
|
||||
if (close) {
|
||||
closed = true;
|
||||
pp.closeSubpath();
|
||||
startPoint = QPointF();
|
||||
}
|
||||
|
||||
p0 = nextPoint;
|
||||
} // of nodes iteration
|
||||
|
||||
if (!closed) {
|
||||
pp.closeSubpath();
|
||||
}
|
||||
|
||||
m_pavements.append(pp);
|
||||
} // of pavements iteration
|
||||
}
|
55
src/GUI/AirportDiagram.hxx
Normal file
55
src/GUI/AirportDiagram.hxx
Normal file
|
@ -0,0 +1,55 @@
|
|||
#include <QWidget>
|
||||
#include <QPainterPath>
|
||||
|
||||
#include <Airports/airports_fwd.hxx>
|
||||
#include <simgear/math/sg_geodesy.hxx>
|
||||
|
||||
class AirportDiagram : public QWidget
|
||||
{
|
||||
public:
|
||||
AirportDiagram(QWidget* pr);
|
||||
|
||||
void setAirport(FGAirportRef apt);
|
||||
|
||||
void addRunway(FGRunwayRef rwy);
|
||||
void addParking(FGParking* park);
|
||||
protected:
|
||||
virtual void paintEvent(QPaintEvent* pe);
|
||||
// wheel event for zoom
|
||||
|
||||
// mouse drag for pan
|
||||
|
||||
|
||||
private:
|
||||
void extendBounds(const QPointF& p);
|
||||
QPointF project(const SGGeod& geod) const;
|
||||
|
||||
void buildTaxiways();
|
||||
void buildPavements();
|
||||
|
||||
FGAirportRef m_airport;
|
||||
SGGeod m_projectionCenter;
|
||||
double m_scale;
|
||||
QRectF m_bounds;
|
||||
|
||||
struct RunwayData {
|
||||
QPointF p1, p2;
|
||||
int widthM;
|
||||
FGRunwayRef runway;
|
||||
};
|
||||
|
||||
QList<RunwayData> m_runways;
|
||||
|
||||
struct TaxiwayData {
|
||||
QPointF p1, p2;
|
||||
int widthM;
|
||||
|
||||
bool operator<(const TaxiwayData& other) const
|
||||
{
|
||||
return widthM < other.widthM;
|
||||
}
|
||||
};
|
||||
|
||||
QList<TaxiwayData> m_taxiways;
|
||||
QList<QPainterPath> m_pavements;
|
||||
};
|
|
@ -53,17 +53,41 @@ if(WIN32)
|
|||
FGWindowsMenuBar.cxx
|
||||
WindowsFileDialog.cxx)
|
||||
endif()
|
||||
|
||||
|
||||
if (APPLE)
|
||||
list(APPEND HEADERS FGCocoaMenuBar.hxx
|
||||
CocoaFileDialog.hxx
|
||||
list(APPEND HEADERS FGCocoaMenuBar.hxx
|
||||
CocoaFileDialog.hxx
|
||||
CocoaMouseCursor.hxx
|
||||
CocoaHelpers.h
|
||||
CocoaHelpers_private.h)
|
||||
list(APPEND SOURCES FGCocoaMenuBar.mm
|
||||
list(APPEND SOURCES FGCocoaMenuBar.mm
|
||||
CocoaFileDialog.mm
|
||||
CocoaMouseCursor.mm
|
||||
CocoaHelpers.mm)
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (HAVE_QT)
|
||||
qt5_wrap_ui(uic_sources Launcher.ui EditRatingsFilterDialog.ui)
|
||||
qt5_add_resources(qrc_sources resources.qrc)
|
||||
|
||||
include_directories(${PROJECT_BINARY_DIR}/src/GUI)
|
||||
|
||||
add_library(fglauncher QtLauncher.cxx
|
||||
QtLauncher.hxx
|
||||
AirportDiagram.cxx
|
||||
AirportDiagram.hxx
|
||||
EditRatingsFilterDialog.cxx
|
||||
EditRatingsFilterDialog.hxx
|
||||
${uic_sources}
|
||||
${qrc_sources})
|
||||
|
||||
target_link_libraries(fglauncher Qt5::Core Qt5::Widgets )
|
||||
|
||||
|
||||
endif()
|
||||
|
||||
|
||||
flightgear_component(GUI "${SOURCES}" "${HEADERS}")
|
||||
|
|
39
src/GUI/EditRatingsFilterDialog.cxx
Normal file
39
src/GUI/EditRatingsFilterDialog.cxx
Normal file
|
@ -0,0 +1,39 @@
|
|||
#include "EditRatingsFilterDialog.hxx"
|
||||
#include "ui_EditRatingsFilterDialog.h"
|
||||
|
||||
EditRatingsFilterDialog::EditRatingsFilterDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::EditRatingsFilterDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
EditRatingsFilterDialog::~EditRatingsFilterDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void EditRatingsFilterDialog::setRatings(int *ratings)
|
||||
{
|
||||
for (int i=0; i<4; ++i) {
|
||||
QAbstractSlider* s = sliderForIndex(i);
|
||||
s->setValue(ratings[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int EditRatingsFilterDialog::getRating(int index) const
|
||||
{
|
||||
return sliderForIndex(index)->value();
|
||||
}
|
||||
|
||||
QAbstractSlider* EditRatingsFilterDialog::sliderForIndex(int index) const
|
||||
{
|
||||
switch (index) {
|
||||
case 0: return ui->fdmSlider;
|
||||
case 1: return ui->systemsSlider;
|
||||
case 2: return ui->cockpitSlider;
|
||||
case 3: return ui->modelSlider;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
29
src/GUI/EditRatingsFilterDialog.hxx
Normal file
29
src/GUI/EditRatingsFilterDialog.hxx
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef EDITRATINGSFILTERDIALOG_HXX
|
||||
#define EDITRATINGSFILTERDIALOG_HXX
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class EditRatingsFilterDialog;
|
||||
}
|
||||
|
||||
class QAbstractSlider;
|
||||
|
||||
class EditRatingsFilterDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit EditRatingsFilterDialog(QWidget *parent = 0);
|
||||
~EditRatingsFilterDialog();
|
||||
|
||||
void setRatings(int* ratings);
|
||||
|
||||
int getRating(int index) const;
|
||||
private:
|
||||
Ui::EditRatingsFilterDialog *ui;
|
||||
|
||||
QAbstractSlider* sliderForIndex(int index) const;
|
||||
};
|
||||
|
||||
#endif // EDITRATINGSFILTERDIALOG_HXX
|
245
src/GUI/EditRatingsFilterDialog.ui
Normal file
245
src/GUI/EditRatingsFilterDialog.ui
Normal file
|
@ -0,0 +1,245 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>EditRatingsFilterDialog</class>
|
||||
<widget class="QDialog" name="EditRatingsFilterDialog">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::WindowModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>623</width>
|
||||
<height>594</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0" colspan="3">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Specify the minimum required completeness of aircraft in each area for it to be shown in the aircraft list.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Cockpit:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QSlider" name="cockpitSlider">
|
||||
<property name="maximum">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="invertedAppearance">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="invertedControls">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TicksBelow</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>3D panel, cockpit and instrumentation status</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Flight model:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QSlider" name="fdmSlider">
|
||||
<property name="maximum">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="invertedAppearance">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="invertedControls">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TicksBelow</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Accuracy of the flight (aerodynamic) model compared to available data and testing/</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Exterior model:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QSlider" name="modelSlider">
|
||||
<property name="maximum">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="invertedAppearance">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="invertedControls">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TicksBelow</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Quality and detail of exterior model, including animated moving parts such as control surfaces and under-carriage</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Systems:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="2">
|
||||
<widget class="QSlider" name="systemsSlider">
|
||||
<property name="maximum">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="invertedAppearance">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="invertedControls">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TicksBelow</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="2">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Completeness of systems modellings, including fuel handling, autopilot operation, startup & failure procedures.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1" colspan="2">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>EditRatingsFilterDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>EditRatingsFilterDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
678
src/GUI/Launcher.ui
Normal file
678
src/GUI/Launcher.ui
Normal file
|
@ -0,0 +1,678 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Launcher</class>
|
||||
<widget class="QDialog" name="Launcher">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>696</width>
|
||||
<height>711</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Start FlightGear</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,1,0">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_2" columnstretch="0,0,1">
|
||||
<item row="3" column="2">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="aircraftDescription">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="airportDescription">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" rowspan="4">
|
||||
<widget class="QLabel" name="thumbnail">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>171</width>
|
||||
<height>128</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Location:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Aircraft:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Settings:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="settingsDescription">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>Aircraft</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="0,0,0">
|
||||
<property name="spacing">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QListView" name="aircraftList"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Search:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="aircraftFilter">
|
||||
<property name="placeholderText">
|
||||
<string>Search aircraft</string>
|
||||
</property>
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="aircraftHistory">
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="ratingsFilterCheck">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Hide aircraft based on completeness (rating)</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="editRatingFilter">
|
||||
<property name="text">
|
||||
<string>Edit...</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
<string>Location</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<property name="leftMargin">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QLabel" name="airportIdent">
|
||||
<property name="text">
|
||||
<string>Search:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="airportEdit">
|
||||
<property name="placeholderText">
|
||||
<string>Enter an ICAO code or search by name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="airportHistory">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="locationStack">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="diagramPage">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="AirportDiagram" name="airportDiagram" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QRadioButton" name="runwayRadio">
|
||||
<property name="text">
|
||||
<string>Runway:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="runwayCombo"/>
|
||||
</item>
|
||||
<item row="2" column="0" rowspan="2">
|
||||
<widget class="QRadioButton" name="parkingRadio">
|
||||
<property name="text">
|
||||
<string>Parking:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="onFinalCheckbox">
|
||||
<property name="text">
|
||||
<string>On 10-mile final</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="parkingCombo"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="searchResultsPage">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QListView" name="searchList"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="searchStatusPage">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<widget class="QLabel" name="searchIcon">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignBottom|Qt::AlignHCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="searchStatusText">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignHCenter|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_3">
|
||||
<attribute name="title">
|
||||
<string>Settings</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Time of day:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="timeOfDayCombo">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Current time</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Dawn</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Morning</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Noon</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Afternoon</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Dusk</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Evening</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Night</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="msaaCheckbox">
|
||||
<property name="text">
|
||||
<string>Enable Multi-sample anti-aliasing</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="rembrandtCheckbox">
|
||||
<property name="text">
|
||||
<string>Enable deferred rendering (Rembrandt)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="terrasyncCheck">
|
||||
<property name="text">
|
||||
<string>Enable automatic scenery downloading (TerraSync)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>If scenery download is disabled, you may need to download additional files from <a href="http://www.flightgear.org/download/scenery/"><span style=" text-decoration: underline; color:#0000ff;">this page</span></a> and install them in a scenery location; otherwise some objects may be missing from the world.</p></body></html></string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="fetchRealWxrCheckbox">
|
||||
<property name="text">
|
||||
<string>Fetch real weather online</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="fullScreenCheckbox">
|
||||
<property name="text">
|
||||
<string>Start full-screen</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="startPausedCheck">
|
||||
<property name="text">
|
||||
<string>Start paused</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3" stretch="1,0">
|
||||
<item>
|
||||
<widget class="QLabel" name="customAircraftDirLabel">
|
||||
<property name="text">
|
||||
<string>Custom aircraft directory:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="openAircraftDirButton">
|
||||
<property name="text">
|
||||
<string>Open in Finder</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Additional scenery locations</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0" colspan="3">
|
||||
<widget class="QListWidget" name="sceneryPathsList"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>567</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QToolButton" name="removeSceneryPath">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>-</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QToolButton" name="addSceneryPath">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>+</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="quitButton">
|
||||
<property name="text">
|
||||
<string>Quit</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>412</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="runButton">
|
||||
<property name="text">
|
||||
<string>Run</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>AirportDiagram</class>
|
||||
<extends>QWidget</extends>
|
||||
<header location="global">GUI/AirportDiagram.hxx</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
1138
src/GUI/QtLauncher.cxx
Normal file
1138
src/GUI/QtLauncher.cxx
Normal file
File diff suppressed because it is too large
Load diff
77
src/GUI/QtLauncher.hxx
Normal file
77
src/GUI/QtLauncher.hxx
Normal file
|
@ -0,0 +1,77 @@
|
|||
|
||||
#include <QDialog>
|
||||
#include <QScopedPointer>
|
||||
#include <QStringList>
|
||||
#include <QModelIndex>
|
||||
|
||||
#include <Airports/airport.hxx>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class Launcher;
|
||||
}
|
||||
|
||||
class AirportSearchModel;
|
||||
class QModelIndex;
|
||||
class AircraftProxyModel;
|
||||
class QCheckBox;
|
||||
|
||||
class QtLauncher : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QtLauncher();
|
||||
virtual ~QtLauncher();
|
||||
|
||||
static bool runLauncherDialog();
|
||||
|
||||
private slots:
|
||||
void onRun();
|
||||
void onQuit();
|
||||
|
||||
void onSearchAirports();
|
||||
|
||||
void onAirportChanged();
|
||||
|
||||
void onAirportChoiceSelected(const QModelIndex& index);
|
||||
void onAircraftSelected(const QModelIndex& index);
|
||||
|
||||
void onPopupAirportHistory();
|
||||
void onPopupAircraftHistory();
|
||||
|
||||
void onOpenCustomAircraftDir();
|
||||
|
||||
void onEditRatingsFilter();
|
||||
|
||||
void updateAirportDescription();
|
||||
void updateSettingsSummary();
|
||||
|
||||
void onAirportSearchComplete();
|
||||
|
||||
void onAddSceneryPath();
|
||||
void onRemoveSceneryPath();
|
||||
private:
|
||||
void setAirport(FGAirportRef ref);
|
||||
void updateSelectedAircraft();
|
||||
|
||||
void restoreSettings();
|
||||
void saveSettings();
|
||||
|
||||
QModelIndex proxyIndexForAircraftPath(QString path) const;
|
||||
QModelIndex sourceIndexForAircraftPath(QString path) const;
|
||||
|
||||
void setEnableDisableOptionFromCheckbox(QCheckBox* cbox, QString name) const;
|
||||
|
||||
QScopedPointer<Ui::Launcher> m_ui;
|
||||
AirportSearchModel* m_airportsModel;
|
||||
AircraftProxyModel* m_aircraftProxy;
|
||||
|
||||
FGAirportRef m_selectedAirport;
|
||||
|
||||
QString m_selectedAircraft;
|
||||
QStringList m_recentAircraft,
|
||||
m_recentAirports;
|
||||
QString m_customAircraftDir;
|
||||
|
||||
int m_ratingFilters[4];
|
||||
};
|
BIN
src/GUI/history-icon.png
Normal file
BIN
src/GUI/history-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.8 KiB |
BIN
src/GUI/large-search-icon.png
Normal file
BIN
src/GUI/large-search-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.7 KiB |
6
src/GUI/resources.qrc
Normal file
6
src/GUI/resources.qrc
Normal file
|
@ -0,0 +1,6 @@
|
|||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file alias="history-icon">history-icon.png</file>
|
||||
<file alias="search-icon">large-search-icon.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
|
@ -46,3 +46,5 @@
|
|||
#cmakedefine HAVE_CRASHRPT
|
||||
|
||||
#cmakedefine ENABLE_FLITE
|
||||
|
||||
#cmakedefine HAVE_QT
|
||||
|
|
|
@ -152,6 +152,10 @@ if(ENABLE_FLITE)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
if (Qt5Core_FOUND)
|
||||
target_link_libraries(fgfs Qt5::Widgets fglauncher)
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
install(TARGETS fgfs BUNDLE DESTINATION .)
|
||||
else()
|
||||
|
|
|
@ -501,25 +501,37 @@ static void initAircraftDirsNasalSecurity()
|
|||
}
|
||||
}
|
||||
|
||||
void fgInitAircraftPaths(bool reinit)
|
||||
{
|
||||
if (!reinit) {
|
||||
SGPath userAircraftDir = SGPath::documents(globals->get_fg_home());
|
||||
if (userAircraftDir != globals->get_fg_home()) {
|
||||
userAircraftDir.append("FlightGear");
|
||||
}
|
||||
userAircraftDir.append("Aircraft");
|
||||
|
||||
SGSharedPtr<Root> pkgRoot(new Root(userAircraftDir, FLIGHTGEAR_VERSION));
|
||||
// set the http client later (too early in startup right now)
|
||||
globals->setPackageRoot(pkgRoot);
|
||||
}
|
||||
|
||||
SGSharedPtr<Root> pkgRoot(globals->packageRoot());
|
||||
SGPropertyNode* aircraftProp = fgGetNode("/sim/aircraft", true);
|
||||
aircraftProp->setAttribute(SGPropertyNode::PRESERVE, true);
|
||||
|
||||
if (!reinit) {
|
||||
flightgear::Options::sharedInstance()->initPaths();
|
||||
}
|
||||
}
|
||||
|
||||
int fgInitAircraft(bool reinit)
|
||||
{
|
||||
if (!reinit) {
|
||||
// FIXME - use Documents/FlightGear/Aircraft
|
||||
SGPath userAircraftDir = globals->get_fg_home();
|
||||
userAircraftDir.append("Aircraft");
|
||||
|
||||
SGSharedPtr<Root> pkgRoot(new Root(userAircraftDir, FLIGHTGEAR_VERSION));
|
||||
// set the http client later (too early in startup right now)
|
||||
globals->setPackageRoot(pkgRoot);
|
||||
}
|
||||
|
||||
SGSharedPtr<Root> pkgRoot(globals->packageRoot());
|
||||
SGPropertyNode* aircraftProp = fgGetNode("/sim/aircraft", true);
|
||||
aircraftProp->setAttribute(SGPropertyNode::PRESERVE, true);
|
||||
|
||||
if (!reinit) {
|
||||
flightgear::Options::sharedInstance()->initAircraft();
|
||||
}
|
||||
|
||||
SGSharedPtr<Root> pkgRoot(globals->packageRoot());
|
||||
SGPropertyNode* aircraftProp = fgGetNode("/sim/aircraft", true);
|
||||
|
||||
string aircraftId(aircraftProp->getStringValue());
|
||||
PackageRef acftPackage = pkgRoot->getPackageById(aircraftId);
|
||||
|
@ -588,7 +600,12 @@ fgInitNav ()
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// depend on when the NavCache was initialised, scenery paths may not
|
||||
// have been setup. This is a safe place to consistently check the value,
|
||||
// and drop the ground-nets if something has changed
|
||||
cache->dropGroundnetsIfRequired();
|
||||
|
||||
FGTACANList *channellist = new FGTACANList;
|
||||
globals->set_channellist( channellist );
|
||||
|
||||
|
@ -1056,6 +1073,7 @@ void fgStartNewReset()
|
|||
}
|
||||
|
||||
fgGetNode("/sim")->removeChild("aircraft-dir");
|
||||
fgInitAircraftPaths(true);
|
||||
fgInitAircraft(true);
|
||||
|
||||
render = new FGRenderer;
|
||||
|
|
|
@ -39,6 +39,8 @@ bool fgInitHome();
|
|||
// Read in configuration (file and command line)
|
||||
int fgInitConfig ( int argc, char **argv, bool reinit );
|
||||
|
||||
void fgInitAircraftPaths(bool reinit);
|
||||
|
||||
int fgInitAircraft(bool reinit);
|
||||
|
||||
// log various settings / configuration state
|
||||
|
|
|
@ -80,6 +80,10 @@ extern bool global_crashRptEnabled;
|
|||
#include "subsystemFactory.hxx"
|
||||
#include "options.hxx"
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
#include <QApplication>
|
||||
#include <GUI/QtLauncher.hxx>
|
||||
#endif
|
||||
|
||||
using namespace flightgear;
|
||||
|
||||
|
@ -394,7 +398,14 @@ static void logToFile()
|
|||
}
|
||||
|
||||
// Main top level initialization
|
||||
int fgMainInit( int argc, char **argv ) {
|
||||
int fgMainInit( int argc, char **argv )
|
||||
{
|
||||
#if defined(HAVE_QT)
|
||||
QApplication app(argc, argv);
|
||||
app.setOrganizationName("FlightGear");
|
||||
app.setApplicationName("FlightGear");
|
||||
app.setOrganizationDomain("flightgear.org");
|
||||
#endif
|
||||
|
||||
// set default log levels
|
||||
sglog().setLogLevels( SG_ALL, SG_ALERT );
|
||||
|
@ -421,11 +432,6 @@ int fgMainInit( int argc, char **argv ) {
|
|||
SG_LOG( SG_GENERAL, SG_INFO, "Jenkins number/ID " << HUDSON_BUILD_NUMBER << ":"
|
||||
<< HUDSON_BUILD_ID);
|
||||
|
||||
// Allocate global data structures. This needs to happen before
|
||||
// we parse command line options
|
||||
|
||||
|
||||
|
||||
// seed the random number generator
|
||||
sg_srandom_time();
|
||||
|
||||
|
@ -447,7 +453,23 @@ int fgMainInit( int argc, char **argv ) {
|
|||
} else if (configResult == flightgear::FG_OPTIONS_EXIT) {
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
// launcher needs to know the aircraft paths in use
|
||||
fgInitAircraftPaths(false);
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
bool showLauncher = flightgear::Options::checkForArg(argc, argv, "launcher");
|
||||
// an Info.plist bundle can't define command line arguments, but it can set
|
||||
// environment variables. This avoids needed a wrapper shell-script on OS-X.
|
||||
showLauncher |= (::getenv("FG_LAUNCHER") != 0);
|
||||
|
||||
if (showLauncher) {
|
||||
if (!QtLauncher::runLauncherDialog()) {
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
configResult = fgInitAircraft(false);
|
||||
if (configResult == flightgear::FG_OPTIONS_ERROR) {
|
||||
return EXIT_FAILURE;
|
||||
|
|
|
@ -1484,6 +1484,7 @@ struct OptionDesc {
|
|||
|
||||
{"language", true, OPTION_IGNORE, "", false, "", 0 },
|
||||
{"console", false, OPTION_IGNORE, "", false, "", 0 },
|
||||
{"launcher", false, OPTION_IGNORE, "", false, "", 0 },
|
||||
{"disable-rembrandt", false, OPTION_BOOL, "/sim/rendering/rembrandt/enabled", false, "", 0 },
|
||||
{"enable-rembrandt", false, OPTION_BOOL, "/sim/rendering/rembrandt/enabled", true, "", 0 },
|
||||
{"renderer", true, OPTION_STRING, "/sim/rendering/rembrandt/renderer", false, "", 0 },
|
||||
|
@ -1953,18 +1954,22 @@ void Options::init(int argc, char **argv, const SGPath& appDataPath)
|
|||
config.append( "system.fgfsrc" );
|
||||
readConfig(config);
|
||||
}
|
||||
|
||||
|
||||
void Options::initPaths()
|
||||
{
|
||||
BOOST_FOREACH(const string& paths, valuesForOption("fg-aircraft")) {
|
||||
globals->append_aircraft_paths(paths);
|
||||
}
|
||||
|
||||
const char* envp = ::getenv("FG_AIRCRAFT");
|
||||
if (envp) {
|
||||
globals->append_aircraft_paths(envp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Options::initAircraft()
|
||||
{
|
||||
BOOST_FOREACH(const string& paths, valuesForOption("fg-aircraft")) {
|
||||
globals->append_aircraft_paths(paths);
|
||||
}
|
||||
|
||||
const char* envp = ::getenv("FG_AIRCRAFT");
|
||||
if (envp) {
|
||||
globals->append_aircraft_paths(envp);
|
||||
}
|
||||
|
||||
string aircraft;
|
||||
if (isOptionSet("aircraft")) {
|
||||
aircraft = valueForOption("aircraft");
|
||||
|
|
|
@ -98,7 +98,12 @@ public:
|
|||
* (set properties, etc).
|
||||
*/
|
||||
OptionResult processOptions();
|
||||
|
||||
|
||||
/**
|
||||
* process command line options relating to scenery / aircraft / data paths
|
||||
*/
|
||||
void initPaths();
|
||||
|
||||
/**
|
||||
* init the aircraft options
|
||||
*/
|
||||
|
|
|
@ -1072,7 +1072,10 @@ NavDataCache::NavDataCache()
|
|||
}
|
||||
|
||||
homePath.append(os.str());
|
||||
|
||||
|
||||
// permit additional DB connections from the same process
|
||||
sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
|
||||
|
||||
for (int t=0; t < MAX_TRIES; ++t) {
|
||||
try {
|
||||
d.reset(new NavDataCachePrivate(homePath, this));
|
||||
|
@ -1162,8 +1165,6 @@ bool NavDataCache::isRebuildRequired()
|
|||
return true;
|
||||
}
|
||||
|
||||
dropGroundnetsIfRequired();
|
||||
|
||||
SG_LOG(SG_NAVCACHE, SG_INFO, "NavCache: no main cache rebuild required");
|
||||
return false;
|
||||
}
|
||||
|
@ -2190,6 +2191,11 @@ bool NavDataCache::isReadOnly() const
|
|||
return d->readOnly;
|
||||
}
|
||||
|
||||
SGPath NavDataCache::path() const
|
||||
{
|
||||
return d->path;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Transaction RAII object
|
||||
|
||||
|
@ -2215,6 +2221,91 @@ void NavDataCache::Transaction::commit()
|
|||
_committed = true;
|
||||
_instance->commitTransaction();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class NavDataCache::ThreadedAirportSearch::ThreadedAirportSearchPrivate : public SGThread
|
||||
{
|
||||
public:
|
||||
ThreadedAirportSearchPrivate() :
|
||||
db(NULL),
|
||||
isComplete(false),
|
||||
quit(false)
|
||||
{}
|
||||
|
||||
virtual void run()
|
||||
{
|
||||
while (!quit) {
|
||||
int err = sqlite3_step(query);
|
||||
if (err == SQLITE_DONE) {
|
||||
break;
|
||||
} else if (err == SQLITE_ROW) {
|
||||
PositionedID r = sqlite3_column_int64(query, 0);
|
||||
SGGuard<SGMutex> g(lock);
|
||||
results.push_back(r);
|
||||
} else if (err == SQLITE_BUSY) {
|
||||
// sleep a tiny amount
|
||||
SGTimeStamp::sleepForMSec(1);
|
||||
} else {
|
||||
std::string errMsg = sqlite3_errmsg(db);
|
||||
SG_LOG(SG_NAVCACHE, SG_ALERT, "Sqlite error:" << errMsg << " running threaded airport query");
|
||||
}
|
||||
}
|
||||
|
||||
SGGuard<SGMutex> g(lock);
|
||||
isComplete = true;
|
||||
}
|
||||
|
||||
SGMutex lock;
|
||||
sqlite3* db;
|
||||
sqlite3_stmt_ptr query;
|
||||
PositionedIDVec results;
|
||||
bool isComplete;
|
||||
bool quit;
|
||||
};
|
||||
|
||||
NavDataCache::ThreadedAirportSearch::ThreadedAirportSearch(const std::string& term) :
|
||||
d(new ThreadedAirportSearchPrivate)
|
||||
{
|
||||
SGPath p = NavDataCache::instance()->path();
|
||||
int openFlags = SQLITE_OPEN_READONLY;
|
||||
std::string pathUtf8 = simgear::strutils::convertWindowsLocal8BitToUtf8(p.str());
|
||||
sqlite3_open_v2(pathUtf8.c_str(), &d->db, openFlags, NULL);
|
||||
|
||||
std::string sql = "SELECT rowid FROM positioned WHERE name LIKE '%" + term
|
||||
+ "%' AND type >= 1 AND type <= 3";
|
||||
sqlite3_prepare_v2(d->db, sql.c_str(), sql.length(), &d->query, NULL);
|
||||
|
||||
d->start();
|
||||
}
|
||||
|
||||
NavDataCache::ThreadedAirportSearch::~ThreadedAirportSearch()
|
||||
{
|
||||
{
|
||||
SGGuard<SGMutex> g(d->lock);
|
||||
d->quit = true;
|
||||
}
|
||||
|
||||
d->join();
|
||||
sqlite3_finalize(d->query);
|
||||
sqlite3_close_v2(d->db);
|
||||
}
|
||||
|
||||
PositionedIDVec NavDataCache::ThreadedAirportSearch::results() const
|
||||
{
|
||||
PositionedIDVec r;
|
||||
{
|
||||
SGGuard<SGMutex> g(d->lock);
|
||||
r = d->results;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
bool NavDataCache::ThreadedAirportSearch::isComplete() const
|
||||
{
|
||||
SGGuard<SGMutex> g(d->lock);
|
||||
return d->isComplete;
|
||||
}
|
||||
|
||||
} // of namespace flightgear
|
||||
|
||||
|
|
|
@ -57,7 +57,9 @@ public:
|
|||
|
||||
// singleton accessor
|
||||
static NavDataCache* instance();
|
||||
|
||||
|
||||
SGPath path() const;
|
||||
|
||||
/**
|
||||
* predicate - check if the cache needs to be rebuilt.
|
||||
* This can happen is the cache file is missing or damaged, or one of the
|
||||
|
@ -277,6 +279,20 @@ public:
|
|||
};
|
||||
|
||||
bool isReadOnly() const;
|
||||
|
||||
class ThreadedAirportSearch
|
||||
{
|
||||
public:
|
||||
ThreadedAirportSearch(const std::string& term);
|
||||
~ThreadedAirportSearch();
|
||||
|
||||
PositionedIDVec results() const;
|
||||
|
||||
bool isComplete() const;
|
||||
private:
|
||||
class ThreadedAirportSearchPrivate;
|
||||
std::auto_ptr<ThreadedAirportSearchPrivate> d;
|
||||
};
|
||||
private:
|
||||
NavDataCache();
|
||||
|
||||
|
|
|
@ -25,6 +25,10 @@
|
|||
|
||||
#include <sstream>
|
||||
|
||||
#if defined(HAVE_QT) && defined(SG_MAC)
|
||||
#include <osgViewer/api/Cocoa/GraphicsWindowCocoa>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
using namespace osg;
|
||||
|
||||
|
@ -244,7 +248,14 @@ GraphicsWindow* WindowBuilder::getDefaultWindow()
|
|||
GraphicsContext::Traits* traits
|
||||
= new GraphicsContext::Traits(*defaultTraits);
|
||||
traits->windowName = "FlightGear";
|
||||
|
||||
|
||||
#if defined(HAVE_QT) && defined(SG_MAC)
|
||||
// avoid both QApplication and OSG::CocoaViewer doing single-application
|
||||
// init (Apple menu, making front process, etc)
|
||||
int flags = osgViewer::GraphicsWindowCocoa::WindowData::CheckForEvents;
|
||||
traits->inheritedWindowData = new osgViewer::GraphicsWindowCocoa::WindowData(flags);
|
||||
#endif
|
||||
|
||||
GraphicsContext* gc = GraphicsContext::createGraphicsContext(traits);
|
||||
if (gc) {
|
||||
defaultWindow = WindowSystemAdapter::getWSA()
|
||||
|
|
Loading…
Add table
Reference in a new issue