Skip to content

Commit

Permalink
Add marker for unsaved changes
Browse files Browse the repository at this point in the history
  • Loading branch information
fboes committed Mar 27, 2019
1 parent 376b382 commit fddbb09
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 28 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ Change log

* 🎁 Add "Update" / "Help" menu entries
* 🎁 Add "Find ICAO airport codes" menu entries
* 🎁 Add marker for unsaved changes

1.1.0
-----
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ _Note:_ The desktop application requires you to actually hit the "Fetch" button

**Important:** Be sure to quit the application before starting Aerofly FS 2 to not accidentally change values while AFS2 is running and to free up memory. Also you may want to backup your `main.mcf` in case something goes wrong.

For troubleshooting look into the [Frequently Asked Questions](docs/faq.md).

HTTP services
-------------

Expand Down
1 change: 1 addition & 0 deletions aerofly-wettergeraet.sln
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
CHANGELOG.md = CHANGELOG.md
docs\configuration.md = docs\configuration.md
CONTRIBUTING.md = CONTRIBUTING.md
docs\faq.md = docs\faq.md
docs\favicon.ico = docs\favicon.ico
docs\issue_template.md = docs\issue_template.md
LICENSE.txt = LICENSE.txt
Expand Down
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
![](./favicon-64x64.png) Documentation
======================================

1. [Frequently Asked Questions](faq.md)
1. [Advanced configuration](configuration.md)
1. [A small guide to METAR information](metar.md)
1. [How these tools interact with Aerofly'S `main.mcf`](aerofly-config.md)
Expand Down
16 changes: 16 additions & 0 deletions docs/faq.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
![](./favicon-64x64.png) Frequently Asked Questions
======================================

Why does the application crash on startup?
------------------------------------------

Make sure to check these settings:

* A `main.mcf` has to be located at `%USERPROFILE%\Documents\Aerofly FS2\main.mcf`. If this is not the case point the tool to the file location by setting the `--file <FILE>` parameter.
* An internet connection to the [AVWX REST API](http://avwx.rest/) is required. If there is an internet connection but AVWX is not reachable, start the tool with the `--url <URL>` parameter set to a different METAR REST API.

If these conditions are met but you are still experiencing crashes, please submit an [issue description](https://github.com/fboes/aerofly-wettergeraet/issues), we'll look into it.

---

Return to [table of contents](README.md).
92 changes: 64 additions & 28 deletions src/WettergeraetDesktop/Frame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@
#include <wx/timectrl.h>
#include <wx/aboutdlg.h>
#include <wx/icon.h>
#include <wx/event.h>
#include <math.h>
#include "Frame.h"
#include "Argumentor.h"
#include "AeroflyConfigFile.h"

const char* Frame::EL_BUTTON_SAVE_LABEL = "Save main.mcf";
const char* Frame::EL_BUTTON_SAVE_LABEL_DIRTY = "Save main.mcf \u2022";

Frame::Frame(const wxString& title, int argc, char * argv[]) : wxFrame(nullptr, wxID_ANY, title, wxPoint(-1, -1), wxSize(640, 480))
{
this->utcDateValue.SetToCurrent();
Expand Down Expand Up @@ -82,15 +86,15 @@ Frame::Frame(const wxString& title, int argc, char * argv[]) : wxFrame(nullptr,
hbox3->Add(utcTimeLabel, 1, wxRIGHT | wxALIGN_CENTER_VERTICAL, labelBorder);

wxDateTime utcDateValue = wxDateTime::Now();
this->utcTimeInput = new wxTimePickerCtrl(panel, wxID_ANY, utcDateValue);
this->utcTimeInput = new wxTimePickerCtrl(panel, Frame::EL_CTRL_DATETIME, utcDateValue);
hbox3->Add(this->utcTimeInput, 1, wxALIGN_CENTER_VERTICAL);

hbox3->Add(10, -1);

wxStaticText *utcDateLabel = new wxStaticText(panel, wxID_ANY, wxT("Date (UTC)"));
hbox3->Add(utcDateLabel, 1, wxALIGN_CENTER_VERTICAL, labelBorder);

this->utcDateInput = new wxDatePickerCtrl(panel, wxID_ANY, utcDateValue);
this->utcDateInput = new wxDatePickerCtrl(panel, Frame::EL_CTRL_DATETIME, utcDateValue);
hbox3->Add(this->utcDateInput, 1, wxLEFT | wxALIGN_CENTER_VERTICAL);
}
vbox->Add(hbox3, 0, wxEXPAND | wxLEFT | wxRIGHT, 10);
Expand All @@ -115,15 +119,15 @@ Frame::Frame(const wxString& title, int argc, char * argv[]) : wxFrame(nullptr,
wxStaticText *clouds0HeightLabel = new wxStaticText(panel, wxID_ANY, cloudName + " height (%)");
hbox8->Add(clouds0HeightLabel, 1, wxRIGHT | wxALIGN_CENTER_VERTICAL, labelBorder);

this->clouds[i].heightInput = new wxSlider(panel, wxID_ANY, 50, 0, 100, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL | wxSL_VALUE_LABEL);
this->clouds[i].heightInput = new wxSlider(panel, Frame::EL_CTRL_SLIDER, 50, 0, 100, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL | wxSL_VALUE_LABEL);
hbox8->Add(this->clouds[i].heightInput, 1, wxALIGN_CENTER_VERTICAL);

hbox8->Add(10, -1);

wxStaticText *clouds0DensityLabel = new wxStaticText(panel, wxID_ANY, cloudName + " density (%)");
hbox8->Add(clouds0DensityLabel, 1, wxALIGN_CENTER_VERTICAL, labelBorder);

this->clouds[i].densityInput = new wxSlider(panel, wxID_ANY, 50, 0, 100, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL | wxSL_VALUE_LABEL);
this->clouds[i].densityInput = new wxSlider(panel, Frame::EL_CTRL_SLIDER, 50, 0, 100, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL | wxSL_VALUE_LABEL);
hbox8->Add(this->clouds[i].densityInput, 1, wxLEFT | wxALIGN_CENTER_VERTICAL);
}
vbox->Add(hbox8, 0, wxEXPAND | wxLEFT | wxRIGHT, 10);
Expand All @@ -136,15 +140,15 @@ Frame::Frame(const wxString& title, int argc, char * argv[]) : wxFrame(nullptr,
wxStaticText *windDirectionLabel = new wxStaticText(panel, wxID_ANY, wxT("Wind direction (\u00B0)"));
hbox5->Add(windDirectionLabel, 1, wxRIGHT | wxALIGN_CENTER_VERTICAL, labelBorder);

this->windDirectionInput = new wxSlider(panel, wxID_ANY, 180, 0, 359, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL | wxSL_VALUE_LABEL);
this->windDirectionInput = new wxSlider(panel, Frame::EL_CTRL_SLIDER, 180, 0, 359, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL | wxSL_VALUE_LABEL);
hbox5->Add(this->windDirectionInput, 1, wxALIGN_CENTER_VERTICAL);

hbox5->Add(10, -1);

wxStaticText *windStrengthLabel = new wxStaticText(panel, wxID_ANY, wxT("Wind strength (%)"));
hbox5->Add(windStrengthLabel, 1, wxALIGN_CENTER_VERTICAL, labelBorder);

this->windStrengthInput = new wxSlider(panel, wxID_ANY, 50, 0, 200, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL | wxSL_VALUE_LABEL);
this->windStrengthInput = new wxSlider(panel, Frame::EL_CTRL_SLIDER, 50, 0, 200, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL | wxSL_VALUE_LABEL);
hbox5->Add(this->windStrengthInput, 1, wxLEFT | wxALIGN_CENTER_VERTICAL);
}
vbox->Add(hbox5, 0, wxEXPAND | wxLEFT | wxRIGHT, 10);
Expand All @@ -156,15 +160,15 @@ Frame::Frame(const wxString& title, int argc, char * argv[]) : wxFrame(nullptr,
wxStaticText *windTurbulenceLabel = new wxStaticText(panel, wxID_ANY, wxT("Turbulence (%)"));
hbox6->Add(windTurbulenceLabel, 1, wxRIGHT | wxALIGN_CENTER_VERTICAL, labelBorder);

this->windTurbulenceInput = new wxSlider(panel, wxID_ANY, 50, 0, 100, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL | wxSL_VALUE_LABEL);
this->windTurbulenceInput = new wxSlider(panel, Frame::EL_CTRL_SLIDER, 50, 0, 100, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL | wxSL_VALUE_LABEL);
hbox6->Add(this->windTurbulenceInput, 1, wxALIGN_CENTER_VERTICAL);

hbox6->Add(10, -1);

wxStaticText *thermalActivityLabel = new wxStaticText(panel, wxID_ANY, wxT("Thermal activity (%)"));
hbox6->Add(thermalActivityLabel, 1, wxALIGN_CENTER_VERTICAL, labelBorder);

this->thermalActivityInput = new wxSlider(panel, wxID_ANY, 50, 0, 100, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL | wxSL_VALUE_LABEL);
this->thermalActivityInput = new wxSlider(panel, Frame::EL_CTRL_SLIDER, 50, 0, 100, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL | wxSL_VALUE_LABEL);
hbox6->Add(this->thermalActivityInput, 1, wxLEFT | wxALIGN_CENTER_VERTICAL);
}
vbox->Add(hbox6, 0, wxEXPAND | wxLEFT | wxRIGHT, 10);
Expand All @@ -176,15 +180,15 @@ Frame::Frame(const wxString& title, int argc, char * argv[]) : wxFrame(nullptr,
wxStaticText *visbilityLabel = new wxStaticText(panel, wxID_ANY, wxT("Visibility (%)"));
hbox7->Add(visbilityLabel, 1, wxRIGHT | wxALIGN_CENTER_VERTICAL, labelBorder);

this->visbilityInput = new wxSlider(panel, wxID_ANY, 50, 0, 100, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL | wxSL_VALUE_LABEL);
this->visbilityInput = new wxSlider(panel, Frame::EL_CTRL_SLIDER, 50, 0, 100, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL | wxSL_VALUE_LABEL);
hbox7->Add(this->visbilityInput, 1, wxALIGN_CENTER_VERTICAL);

hbox7->Add(10, -1);

wxStaticText *noLabel = new wxStaticText(panel, wxID_ANY, wxT(""));
hbox7->Add(noLabel, 1, wxLEFT | wxALIGN_CENTER_VERTICAL);

this->saveButton = new wxButton(panel, wxID_SAVE, wxT("Save main.mcf"), wxPoint(5, 5));
this->saveButton = new wxButton(panel, wxID_SAVE, this->EL_BUTTON_SAVE_LABEL_DIRTY, wxPoint(5, 5));
hbox7->Add(this->saveButton, 1, wxLEFT | wxALIGN_CENTER_VERTICAL);
}
vbox->Add(hbox7, 0, wxEXPAND | wxLEFT | wxRIGHT, 10);
Expand Down Expand Up @@ -257,23 +261,40 @@ void Frame::fromInputToObject()
}
}

void Frame::markAsClean()
{
this->saveButton->SetLabel(this->EL_BUTTON_SAVE_LABEL);
}

void Frame::markAsDirty()
{
this->saveButton->SetLabel(this->EL_BUTTON_SAVE_LABEL_DIRTY);
}

void Frame::loadMainMcf()
{
this->mainConfig.setFilename(this->argumentor.filename);
this->mainConfig.load();
this->mainConfig.getToAeroflyObject(this->aerofly);
this->utcDateValue.SetToCurrent();
this->metarInput->SetValue("");
std::string origin;
std::string destination;
std::tie(origin, destination) = this->mainConfig.getFlightplan();
if (origin != "") {
strcpy(this->aerofly.nearestAirport, origin.c_str());
try {
this->mainConfig.setFilename(this->argumentor.filename);
this->mainConfig.load();
this->mainConfig.getToAeroflyObject(this->aerofly);
this->utcDateValue.SetToCurrent();
this->metarInput->SetValue("");
std::string origin;
std::string destination;
std::tie(origin, destination) = this->mainConfig.getFlightplan();
if (origin != "") {
strcpy(this->aerofly.nearestAirport, origin.c_str());
}
else {
strcpy(this->aerofly.nearestAirport, this->argumentor.icaoCode);
}
this->fromObjectToInput();
this->markAsClean();
}
else {
strcpy(this->aerofly.nearestAirport, this->argumentor.icaoCode);
catch (std::invalid_argument& e) {
this->metarInput->SetValue(e.what());
return;
}
this->fromObjectToInput();
}

// --------------------------------------------------------------------------------------
Expand All @@ -291,6 +312,7 @@ void Frame::actionFetch(wxCommandEvent& WXUNUSED(event))
auto metarString = urlFetcher.fetch(this->argumentor.url, icaoCode, this->argumentor.response, this->argumentor.apikey);
this->metarInput->SetValue(metarString);
this->saveButton->SetFocus();
this->markAsDirty();
}
catch (std::invalid_argument& e) {
this->metarInput->SetValue(e.what());
Expand All @@ -315,10 +337,17 @@ void Frame::actionParse(wxCommandEvent& WXUNUSED(event))
void Frame::actionSave(wxCommandEvent& WXUNUSED(event))
{
if (!this->argumentor.isDryRun) {
this->fromInputToObject();
this->mainConfig.setFromAeroflyObject(this->aerofly);
this->mainConfig.save();
try {
this->fromInputToObject();
this->mainConfig.setFromAeroflyObject(this->aerofly);
this->mainConfig.save();
}
catch (std::invalid_argument& e) {
this->metarInput->SetValue(e.what());
return;
}
}
this->markAsClean();
}

void Frame::actionExit(wxCommandEvent& WXUNUSED(event))
Expand Down Expand Up @@ -361,14 +390,21 @@ void Frame::actionFindIcao(wxCommandEvent& WXUNUSED(event))
wxLaunchDefaultBrowser("https://www.world-airport-codes.com/");
}

void Frame::actionMarkAsDirty(wxCommandEvent& WXUNUSED(event))
{
this->markAsDirty();
}

wxBEGIN_EVENT_TABLE(Frame, wxFrame)
EVT_BUTTON(Frame::EL_BUTTON_FETCH, Frame::actionFetch)
EVT_BUTTON(wxID_SAVE, Frame::actionSave)
EVT_MENU(wxID_HELP, Frame::actionHelp)
EVT_MENU(EL_MENU_UPDATE, Frame::actionUpdate)
EVT_MENU(EL_MENU_FIND_ICAO, Frame::actionFindIcao)
EVT_MENU(Frame::EL_MENU_UPDATE, Frame::actionUpdate)
EVT_MENU(Frame::EL_MENU_FIND_ICAO, Frame::actionFindIcao)
EVT_MENU(wxID_ABOUT, Frame::actionAbout)
EVT_MENU(wxID_EXIT, Frame::actionExit)
EVT_MENU(wxID_OPEN, Frame::actionLoadMainMcf)
EVT_TEXT(Frame::EL_CTRL_METAR, Frame::actionParse)
EVT_SLIDER(Frame::EL_CTRL_SLIDER, Frame::actionMarkAsDirty)
//EVT_DATE_CHANGED(Frame::EL_CTRL_DATETIME, Frame::actionMarkAsDirty)
wxEND_EVENT_TABLE()
11 changes: 11 additions & 0 deletions src/WettergeraetDesktop/Frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ class Frame : public wxFrame
cloudsInputs clouds[3]; // "cirrus", "cumulus", "cumulus_mediocris"
wxButton *saveButton;

static const char* EL_BUTTON_SAVE_LABEL;
static const char* EL_BUTTON_SAVE_LABEL_DIRTY;

DECLARE_EVENT_TABLE()

public:
Expand All @@ -56,6 +59,12 @@ class Frame : public wxFrame
// Copy state of form to objects
virtual void fromInputToObject();

// Show user that current state has been saved.
virtual void markAsClean();

// Show user that current state has not yet been saved.
virtual void markAsDirty();

virtual void loadMainMcf();

// Fetch new METAR data
Expand All @@ -79,4 +88,6 @@ class Frame : public wxFrame

virtual void actionFindIcao(wxCommandEvent&);

virtual void actionMarkAsDirty(wxCommandEvent&);

};

0 comments on commit fddbb09

Please sign in to comment.