#include <Airports/xmlloader.hxx>
#include <Network/HTTPClient.hxx>
#include <Viewer/viewmgr.hxx>
-#include <Viewer/viewer.hxx>
+#include <Viewer/view.hxx>
#include <Environment/presets.hxx>
#include <Navaids/NavDataCache.hxx>
# include <google/profiler.h>
#endif
+#if defined(HAVE_QT)
+#include <GUI/QtLauncher.hxx>
+#endif
+
using std::string;
using std::ifstream;
using std::ofstream;
fgSetBool("/sim/freeze/clock",!paused);
}
- SGPropertyNode_ptr args(new SGPropertyNode);
- args->setStringValue("id", "sim-pause");
- if (!paused && fgGetBool("/sim/view-name-popup")) {
- args->setStringValue("label", "Simulation is paused");
- globals->get_commands()->execute("show-message", args);
- } else {
- globals->get_commands()->execute("clear-message", args);
- }
-
+ syncPausePopupState();
return true;
}
if (file.extension() != "sav")
file.concat(".sav");
- if (fgValidatePath(file, false).empty()) {
+ std::string validated_path = fgValidatePath(file, false);
+ if (validated_path.empty()) {
SG_LOG(SG_IO, SG_ALERT, "load: reading '" << file << "' denied "
"(unauthorized access)");
return false;
}
- ifstream input(file.c_str());
+ ifstream input(validated_path.c_str());
if (input.good() && fgLoadFlight(input)) {
input.close();
SG_LOG(SG_INPUT, SG_INFO, "Restored flight from " << file);
if (file.extension() != "sav")
file.concat(".sav");
- if (fgValidatePath(file, false).empty()) {
+ std::string validated_path = fgValidatePath(file, true);
+ if (validated_path.empty()) {
SG_LOG(SG_IO, SG_ALERT, "save: writing '" << file << "' denied "
"(unauthorized access)");
return false;
bool write_all = arg->getBoolValue("write-all", false);
SG_LOG(SG_INPUT, SG_INFO, "Saving flight");
- ofstream output(file.c_str());
+ ofstream output(validated_path.c_str());
if (output.good() && fgSaveFlight(output, write_all)) {
output.close();
SG_LOG(SG_INPUT, SG_INFO, "Saved flight to " << file);
return openBrowser(path);
}
+static bool
+do_open_launcher(const SGPropertyNode *)
+{
+#if defined(HAVE_QT)
+ bool ok = flightgear::runInAppLauncherDialog();
+ if (ok) {
+ // start a full reset
+ fgResetIdleState();
+ }
+ return ok;
+#else
+ return false;
+#endif
+}
+
/**
* Apply a value in the active XML-configured dialog.
*
return true;
}
-/**
- * Built-in command: play an audio message (i.e. a wav file) This is
- * fire and forget. Call this once per message and it will get dumped
- * into a queue. Messages are played sequentially so they do not
- * overlap.
- */
-static bool
-do_play_audio_sample (const SGPropertyNode * arg)
-{
- SGSoundMgr *smgr = globals->get_soundmgr();
- if (!smgr) {
- SG_LOG(SG_GENERAL, SG_WARN, "play-audio-sample: sound-manager not running");
- return false;
- }
-
- string path = arg->getStringValue("path");
- string file = arg->getStringValue("file");
- float volume = arg->getFloatValue("volume");
- // cout << "playing " << path << " / " << file << endl;
- try {
- FGSampleQueue *queue = globals->get_chatter_queue();
- if ( !queue ) {
- queue = new FGSampleQueue(smgr, "chatter");
- queue->tie_to_listener();
- globals->set_chatter_queue(queue);
- }
-
- SGSoundSample *msg = new SGSoundSample(file.c_str(), path);
- msg->set_volume( volume );
- queue->add( msg );
-
- return true;
-
- } catch (const sg_io_exception&) {
- SG_LOG(SG_GENERAL, SG_ALERT, "play-audio-sample: "
- "failed to load" << path << '/' << file);
- return false;
- }
-}
-
/**
* Built-in command: commit presets (read from in /sim/presets/)
*/
}
}
- if (fgValidatePath(file, false).empty()) {
+ std::string validated_path = fgValidatePath(file, false);
+ if (validated_path.empty()) {
SG_LOG(SG_IO, SG_ALERT, "loadxml: reading '" << file.str() << "' denied "
- "(unauthorized access)");
+ "(unauthorized directory - authorization no longer follows symlinks; to authorize reading additional directories, add them to --fg-aircraft)");
return false;
}
targetnode = const_cast<SGPropertyNode *>(arg)->getNode("data", true);
try {
- readProperties(file.c_str(), targetnode, true);
+ readProperties(validated_path.c_str(), targetnode, true);
} catch (const sg_exception &e) {
SG_LOG(SG_IO, SG_WARN, "loadxml: " << e.getFormattedMessage());
return false;
if (file.extension() != "xml")
file.concat(".xml");
- if (fgValidatePath(file, true).empty()) {
+ std::string validated_path = fgValidatePath(file, true);
+ if (validated_path.empty()) {
SG_LOG(SG_IO, SG_ALERT, "savexml: writing to '" << file.str() << "' denied "
- "(unauthorized access)");
+ "(unauthorized directory - authorization no longer follows symlinks)");
return false;
}
return false;
try {
- writeProperties (file.c_str(), sourcenode, true);
+ writeProperties (validated_path.c_str(), sourcenode, true);
} catch (const sg_exception &e) {
SG_LOG(SG_IO, SG_WARN, "savexml: " << e.getFormattedMessage());
return false;
static bool
do_set_scenery_paths(const SGPropertyNode* arg)
{
- SGPropertyNode* sim = fgGetNode("/sim", true);
- sim->removeChildren("fg-scenery");
-
globals->clear_fg_scenery();
std::string terrasyncPath(fgGetString("/sim/terrasync/scenery-dir"));
globals->append_fg_scenery(root.str());
}
- // might need to drop ground-nets from the DB. Also need to drop
- // them from memory, but this is tricky since FGAirportDynamics holds
- // an instance directly, and AI code may have pointers to ground-net
- // nodes. For now we'll leave-in memory versions untouched.
- flightgear::NavDataCache::instance()->dropGroundnetsIfRequired();
-
return true;
}
{ "open-browser", do_open_browser },
{ "gui-redraw", do_gui_redraw },
{ "add-model", do_add_model },
- { "play-audio-sample", do_play_audio_sample },
{ "presets-commit", do_presets_commit },
{ "log-level", do_log_level },
{ "replay", do_replay },
+ { "open-launcher", do_open_launcher },
/*
{ "decrease-visibility", do_decrease_visibility },
{ "increase-visibility", do_increase_visibility },