Navigation Menu

Skip to content

Commit

Permalink
Added separate export menu item for X-IvAp since format differs sligh…
Browse files Browse the repository at this point in the history
…tly from IvAp.

Fixed small isses with export format.
Alternate airports are now pre-filled in online format export.
Now setting dialog window titles using export format.

closes #395
  • Loading branch information
albar965 committed Aug 26, 2019
1 parent 675d523 commit c08e0ec
Show file tree
Hide file tree
Showing 8 changed files with 188 additions and 59 deletions.
2 changes: 2 additions & 0 deletions src/gui/mainwindow.cpp
Expand Up @@ -1190,6 +1190,7 @@ void MainWindow::connectAllSlots()
// Online export options
connect(ui->actionRouteSaveAsVfp, &QAction::triggered, routeExport, &RouteExport::routeExportVfp);
connect(ui->actionRouteSaveAsIvap, &QAction::triggered, routeExport, &RouteExport::routeExportIvap);
connect(ui->actionRouteSaveAsXIvap, &QAction::triggered, routeExport, &RouteExport::routeExportXIvap);

connect(routeFileHistory, &FileHistoryHandler::fileSelected, this, &MainWindow::routeOpenRecent);

Expand Down Expand Up @@ -3372,6 +3373,7 @@ void MainWindow::updateActionStates()

ui->actionRouteSaveAsVfp->setEnabled(hasFlightplan);
ui->actionRouteSaveAsIvap->setEnabled(hasFlightplan);
ui->actionRouteSaveAsXIvap->setEnabled(hasFlightplan);
ui->actionRouteShowSkyVector->setEnabled(hasFlightplan);

ui->actionRouteCenter->setEnabled(hasFlightplan);
Expand Down
18 changes: 15 additions & 3 deletions src/gui/mainwindow.ui
Expand Up @@ -95,6 +95,7 @@
</property>
<addaction name="actionRouteSaveAsVfp"/>
<addaction name="actionRouteSaveAsIvap"/>
<addaction name="actionRouteSaveAsXIvap"/>
</widget>
<addaction name="actionRouteNew"/>
<addaction name="actionRouteOpen"/>
Expand Down Expand Up @@ -10247,13 +10248,13 @@ relation to shown airport</string>
</action>
<action name="actionRouteSaveAsIvap">
<property name="text">
<string>Export Flight Plan as &amp;IvAp or X-IvAp FPL ...</string>
<string>Export Flight Plan as &amp;IvAp FPL ...</string>
</property>
<property name="toolTip">
<string>Save flight plan as FPL file for IvAp or X-IvAp</string>
<string>Save flight plan as FPL file for IvAp</string>
</property>
<property name="statusTip">
<string>Save flight plan as FPL file for IvAp or X-IvAp</string>
<string>Save flight plan as FPL file for IvAp</string>
</property>
</action>
<action name="actionShortcutMap">
Expand Down Expand Up @@ -10879,6 +10880,17 @@ relation to shown airport</string>
<string>Hide or show columns in table</string>
</property>
</action>
<action name="actionRouteSaveAsXIvap">
<property name="text">
<string>Export Flight Plan as X-IvAp FPL ...</string>
</property>
<property name="toolTip">
<string>Save flight plan as FPL file for X-IvAp</string>
</property>
<property name="statusTip">
<string>Save flight plan as FPL file for X-IvAp</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<tabstops>
Expand Down
22 changes: 13 additions & 9 deletions src/route/route.cpp
Expand Up @@ -233,11 +233,6 @@ bool Route::isSmaller(const atools::geo::LineDistance& dist1, const atools::geo:
return std::abs(dist1.distance) < std::abs(dist2.distance) + epsilon;
}

void Route::updateActivePos(const map::PosCourse& pos)
{
activePos = pos;
}

void Route::updateActiveLegAndPos(const map::PosCourse& pos)
{
if(isEmpty() || !pos.isValid())
Expand Down Expand Up @@ -1011,10 +1006,7 @@ void Route::updateAlternateProperties()
int offset = getAlternateLegsOffset();
if(offset != map::INVALID_INDEX_VALUE)
{
QStringList alternates;
for(int idx = offset; idx < offset + getNumAlternateLegs(); idx++)
alternates.append(at(idx).getIdent());

QStringList alternates = getAlternateIdents();
if(!alternates.isEmpty())
getFlightplan().getProperties().insert(atools::fs::pln::ALTERNATES, alternates.join("#"));
else
Expand All @@ -1024,6 +1016,18 @@ void Route::updateAlternateProperties()
getFlightplan().getProperties().remove(atools::fs::pln::ALTERNATES);
}

QStringList Route::getAlternateIdents() const
{
QStringList alternates;
int offset = getAlternateLegsOffset();
if(offset != map::INVALID_INDEX_VALUE)
{
for(int idx = offset; idx < offset + getNumAlternateLegs(); idx++)
alternates.append(at(idx).getIdent());
}
return alternates;
}

QBitArray Route::getJetAirwayFlags() const
{
QBitArray flags(size());
Expand Down
8 changes: 7 additions & 1 deletion src/route/route.h
Expand Up @@ -529,13 +529,19 @@ class Route :

void clearFlightplanAlternateProperties();

/* Get ICAO idents of all alternates */
QStringList getAlternateIdents() const;
void updateAlternateProperties();

/* Get a bit array which indicates high/low airways - needed for some export formats.
* True indicates high airway used towards waypoint at the same index. */
QBitArray getJetAirwayFlags() const;

void updateActivePos(const map::PosCourse& pos);
/* Update current position only */
void updateActivePos(const map::PosCourse& pos)
{
activePos = pos;
}

private:
/* Remove any waypoints which positions overlap with procedures. Requires a flight plan that is cleaned up and contains
Expand Down
111 changes: 79 additions & 32 deletions src/route/routeexport.cpp
Expand Up @@ -670,27 +670,39 @@ bool RouteExport::routeExportVfp()
return false;
}

bool RouteExport::routeExportXIvap()
{
return routeExportIvapInternal(re::XIVAP);
}

bool RouteExport::routeExportIvap()
{
return routeExportIvapInternal(re::IVAP);
}

bool RouteExport::routeExportIvapInternal(re::RouteExportType type)
{
qDebug() << Q_FUNC_INFO;

if(routeValidate(false /* validate parking */, true /* validate departure and destination */))
{
RouteExportData exportData = createRouteExportData(re::IVAP);
if(routeExportDialog(exportData, re::IVAP))
RouteExportData exportData = createRouteExportData(type);
if(routeExportDialog(exportData, type))
{
QString typeStr = RouteExportDialog::getRouteTypeAsDisplayString(type);
QString routeFile = dialog->saveFileDialog(
tr("Export Flight Plan as IvAp/X-IvAp FPL"),
tr("FPL Files %1;;All Files (*)").arg(lnm::FILE_PATTERN_FPL), "fpl", "Route/Ivap",
tr("Export Flight Plan as %1 FPL").arg(typeStr),
tr("FPL Files %1;;All Files (*)").arg(lnm::FILE_PATTERN_FPL), "fpl",
"Route/" + RouteExportDialog::getRouteTypeAsString(type),
documentsLocation,
buildDefaultFilenameShort(QString(), ".fpl"),
false /* confirm overwrite */, OptionData::instance().getFlags2() & opts2::PROPOSE_FILENAME);

if(!routeFile.isEmpty())
{
if(exportFlighplanAsIvap(exportData, routeFile))
if(exportFlighplanAsIvap(exportData, routeFile, type))
{
mainWindow->setStatusMessage(tr("Flight plan saved for IvAp/X-IvAp."));
mainWindow->setStatusMessage(tr("Flight plan saved for %1.").arg(typeStr));
return true;
}
}
Expand All @@ -702,6 +714,7 @@ bool RouteExport::routeExportIvap()
RouteExportData RouteExport::createRouteExportData(re::RouteExportType routeExportType)
{
RouteExportData exportData;

const Route& route = NavApp::getRouteConst();
exportData.setRoute(RouteString::createStringForRoute(route, 0.f, rs::SID_STAR));
exportData.setDeparture(route.getFlightplan().getDepartureIdent());
Expand All @@ -710,6 +723,12 @@ RouteExportData RouteExport::createRouteExportData(re::RouteExportType routeExpo
exportData.setDepartureTimeActual(QDateTime::currentDateTimeUtc().time());
exportData.setCruiseAltitude(atools::roundToInt(route.getCruisingAltitudeFeet()));

QStringList alternates = route.getAlternateIdents();
if(alternates.size() > 0)
exportData.setAlternate(alternates.at(0));
if(alternates.size() > 1)
exportData.setAlternate2(alternates.at(1));

atools::fs::pln::FlightplanType flightplanType = route.getFlightplan().getFlightplanType();
switch(routeExportType)
{
Expand All @@ -724,6 +743,7 @@ RouteExportData RouteExport::createRouteExportData(re::RouteExportType routeExpo
break;

case re::IVAP:
case re::XIVAP:

// [FLIGHTPLAN]
// FLIGHTTYPE=N
Expand Down Expand Up @@ -1130,7 +1150,8 @@ bool RouteExport::exportFlighplanAsVfp(const RouteExportData& exportData, const
}
}

bool RouteExport::exportFlighplanAsIvap(const RouteExportData& exportData, const QString& filename)
bool RouteExport::exportFlighplanAsIvap(const RouteExportData& exportData, const QString& filename,
re::RouteExportType type)
{
QFile file(filename);
if(file.open(QFile::WriteOnly | QIODevice::Text))
Expand Down Expand Up @@ -1164,31 +1185,43 @@ bool RouteExport::exportFlighplanAsIvap(const RouteExportData& exportData, const
// RULES=I
QTextStream stream(&file);
stream << "[FLIGHTPLAN]" << endl;
stream << "CALLSIGN=" << exportData.getCallsign() << endl;
stream << "PIC=" << exportData.getPilotInCommand() << endl;
stream << "LIVERY=" << exportData.getLivery() << endl;
stream << "AIRLINE=" << exportData.getAirline() << endl;
stream << "SPEEDTYPE=N" << endl;
stream << "POB=" << exportData.getPassengers() << endl;
stream << "ENDURANCE=" << minToHourMinStr(exportData.getEnduranceMinutes()) << endl;
stream << "OTHER=" << exportData.getRemarks() << endl;
stream << "ALT2ICAO=" << exportData.getAlternate2() << endl;
stream << "ALTICAO=" << exportData.getAlternate() << endl;
stream << "EET=" << minToHourMinStr(exportData.getEnrouteMinutes()) << endl;
stream << "DESTICAO=" << exportData.getDestination() << endl;
stream << "ROUTE=" << exportData.getRoute() << endl;
stream << "LEVEL=" << exportData.getCruiseAltitude() / 100 << endl;
stream << "LEVELTYPE=F" << endl;
stream << "SPEED=" << exportData.getSpeed() << endl;
stream << "DEPTIME=" << exportData.getDepartureTime().toString("HHmm") << endl;
stream << "DEPICAO=" << exportData.getDeparture() << endl;
stream << "TRANSPONDER=" << exportData.getTransponder() << endl;
stream << "EQUIPMENT=" << exportData.getEquipment() << endl;
stream << "WAKECAT=" << exportData.getWakeCategory() << endl;
stream << "ACTYPE=" << exportData.getAircraftType() << endl;
stream << "NUMBER=1" << endl;
stream << "FLIGHTTYPE=" << exportData.getFlightType() << endl;
stream << "RULES=" << exportData.getFlightRules() << endl;

if(type == re::XIVAP)
{
stream << endl;
writeIvapLine(stream, "CALLSIGN", exportData.getCallsign(), type);
writeIvapLine(stream, "LIVERY", exportData.getLivery(), type);
writeIvapLine(stream, "AIRLINE", exportData.getAirline(), type);
writeIvapLine(stream, "PIC", exportData.getPilotInCommand(), type);
writeIvapLine(stream, "ALT2ICAO", exportData.getAlternate2(), type);
writeIvapLine(stream, "FMCROUTE", QString(), type);
}
else
{
writeIvapLine(stream, "ID", exportData.getCallsign(), type);
writeIvapLine(stream, "ALTICAO2", exportData.getAlternate2(), type);
}

writeIvapLine(stream, "SPEEDTYPE", "N", type);
writeIvapLine(stream, "POB", exportData.getPassengers(), type);
writeIvapLine(stream, "ENDURANCE", minToHourMinStr(exportData.getEnduranceMinutes()), type);
writeIvapLine(stream, "OTHER", exportData.getRemarks(), type);
writeIvapLine(stream, "ALTICAO", exportData.getAlternate(), type);
writeIvapLine(stream, "EET", minToHourMinStr(exportData.getEnrouteMinutes()), type);
writeIvapLine(stream, "DESTICAO", exportData.getDestination(), type);
writeIvapLine(stream, "ROUTE", exportData.getRoute(), type);
writeIvapLine(stream, "LEVEL", exportData.getCruiseAltitude() / 100, type);
writeIvapLine(stream, "LEVELTYPE", "F", type);
writeIvapLine(stream, "SPEED", exportData.getSpeed(), type);
writeIvapLine(stream, "DEPTIME", exportData.getDepartureTime().toString("HHmm"), type);
writeIvapLine(stream, "DEPICAO", exportData.getDeparture(), type);
writeIvapLine(stream, "TRANSPONDER", exportData.getTransponder(), type);
writeIvapLine(stream, "EQUIPMENT", exportData.getEquipment(), type);
writeIvapLine(stream, "WAKECAT", exportData.getWakeCategory(), type);
writeIvapLine(stream, "ACTYPE", exportData.getAircraftType(), type);
writeIvapLine(stream, "NUMBER", "1", type);
writeIvapLine(stream, "FLIGHTTYPE", exportData.getFlightType(), type);
writeIvapLine(stream, "RULES", exportData.getFlightRules(), type);

file.close();
return true;
Expand Down Expand Up @@ -1447,3 +1480,17 @@ QString RouteExport::minToHourMinStr(int minutes)
int enrouteHours = minutes / 60;
return QString("%1%2").arg(enrouteHours, 2, 10, QChar('0')).arg(minutes - enrouteHours * 60, 2, 10, QChar('0'));
}

void RouteExport::writeIvapLine(QTextStream& stream, const QString& key, const QString& value, re::RouteExportType type)
{
stream << key << "=" << value << endl;
if(type == re::XIVAP)
stream << endl;
}

void RouteExport::writeIvapLine(QTextStream& stream, const QString& key, int value, re::RouteExportType type)
{
stream << key << "=" << value << endl;
if(type == re::XIVAP)
stream << endl;
}
9 changes: 8 additions & 1 deletion src/route/routeexport.h
Expand Up @@ -42,6 +42,7 @@ class Dialog;
class MainWindow;
class Route;
class RouteExportData;
class QTextStream;

/*
* Covers all flight plan export and export related functions including validation and warning dialogs.
Expand Down Expand Up @@ -104,6 +105,7 @@ class RouteExport :

/* IVAP or X-IVAP for IVAO */
bool routeExportIvap();
bool routeExportXIvap();

/* FeelThere or Wilco aircraft */
bool routeExportFeelthereFpl();
Expand Down Expand Up @@ -164,6 +166,8 @@ class RouteExport :
bool exportFlighplan(const QString& filename, std::function<void(const atools::fs::pln::Flightplan&,
const QString&)> exportFunc);

bool routeExportIvapInternal(re::RouteExportType type);

/* Show online network dialog which allows the user to enter needed data */
bool routeExportDialog(RouteExportData& exportData, re::RouteExportType flightplanType);

Expand All @@ -174,9 +178,12 @@ class RouteExport :
bool exportFlighplanAsVfp(const RouteExportData& exportData, const QString& filename);

/* Export IVAP or X-IVAP */
bool exportFlighplanAsIvap(const RouteExportData& exportData, const QString& filename);
bool exportFlighplanAsIvap(const RouteExportData& exportData, const QString& filename, re::RouteExportType type);
QString minToHourMinStr(int minutes);

void writeIvapLine(QTextStream& stream, const QString& key, const QString& value, re::RouteExportType type);
void writeIvapLine(QTextStream& stream, const QString& key, int value, re::RouteExportType type);

MainWindow *mainWindow;
atools::gui::Dialog *dialog;
atools::fs::pln::FlightplanIO *flightplanIO;
Expand Down

0 comments on commit c08e0ec

Please sign in to comment.