// This file is part of fityk program. Copyright (C) Marcin Wojdyr // Licence: GNU General Public License version 2 // $Id: app.cpp 345 2007-08-21 01:09:15Z wojdyr $ // wxwindows headers, see wxwindows samples for description #include #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include #endif #include #include #include #include #include #if wxUSE_TOOLTIPS #include #endif #include #include #include "app.h" #include "cmn.h" #include "gui.h" #include "dataedit.h" //DataEditorDlg::read_transforms() #include "pane.h" // initializations #include "sidebar.h" // initializations #include "../logic.h" #include "../cmd.h" using namespace std; IMPLEMENT_APP(FApp) /// command line options static const wxCmdLineEntryDesc cmdLineDesc[] = { { wxCMD_LINE_SWITCH, wxT("h"), wxT("help"), wxT("show this help message"), wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP }, { wxCMD_LINE_SWITCH, wxT("V"), wxT("version"), wxT("output version information and exit"), wxCMD_LINE_VAL_NONE, 0 }, { wxCMD_LINE_OPTION, wxT("c"),wxT("cmd"), wxT("script passed in as string"), wxCMD_LINE_VAL_STRING, 0 }, { wxCMD_LINE_OPTION, wxT("g"),wxT("config"), wxT("choose GUI configuration"), wxCMD_LINE_VAL_STRING, 0 }, { wxCMD_LINE_SWITCH, wxT("I"), wxT("no-init"), wxT("don't process $HOME/.fityk/init file"), wxCMD_LINE_VAL_NONE, 0 }, { wxCMD_LINE_SWITCH, wxT("r"), wxT("reorder"), wxT("reorder data (50.xy before 100.xy)"), wxCMD_LINE_VAL_NONE, 0 }, { wxCMD_LINE_PARAM, 0, 0, wxT("script or data file"),wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL|wxCMD_LINE_PARAM_MULTIPLE }, { wxCMD_LINE_NONE, 0, 0, 0, wxCMD_LINE_VAL_NONE, 0 } }; //---------------- C A L L B A C K S -------------------------------------- void gui_show_message(OutputStyle style, const string& s) { frame->output_text(style, s + "\n"); } void gui_do_draw_plot(bool now) { frame->refresh_plots(now); } void gui_wait(float seconds) { wxMilliSleep(iround(seconds*1e3)); } void gui_refresh() { wxSafeYield(); } Commands::Status gui_exec_command(const string& s) { //FIXME should I limit number of displayed lines? //const int max_lines_in_output_win = 1000; //don't output plot command - it is generated by every zoom in/out etc. bool output = strncmp(s.c_str(), "plot", 4) != 0; if (output) frame->output_text(os_input, "=-> " + s + "\n"); else frame->set_status_text(s); wxBusyCursor wait; Commands::Status r; try { r = parse_and_execute(s); } catch(ExitRequestedException) { frame->Close(true); return Commands::status_ok; } frame->after_cmd_updates(); return r; } //------------------------------------------------------------------------- bool FApp::OnInit(void) { SetAppName(wxT("fityk")); // if options can be parsed wxCmdLineParser cmdLineParser(cmdLineDesc, argc, argv); if (cmdLineParser.Parse(false) != 0) { cmdLineParser.Usage(); return false; //false = exit the application } else if (cmdLineParser.Found(wxT("V"))) { wxMessageOutput::Get()->Printf(wxT("fityk version ") + pchar2wx(VERSION) + wxT("\n")); return false; //false = exit the application } //the rest of options will be processed in process_argv() ftk = new Ftk; // set callbacks ftk->get_ui()->set_show_message(gui_show_message); ftk->get_ui()->set_do_draw_plot(gui_do_draw_plot); ftk->get_ui()->set_wait(gui_wait); ftk->get_ui()->set_refresh(gui_refresh); ftk->get_ui()->set_exec_command(gui_exec_command); wxFileSystem::AddHandler(new wxZipFSHandler); wxImage::AddHandler(new wxPNGHandler); //global settings #if wxUSE_TOOLTIPS wxToolTip::Enable (true); wxToolTip::SetDelay (500); #endif //create user data directory, if it doesn't exists wxString fityk_dir = wxStandardPaths::Get().GetUserDataDir(); if (!wxDirExists(fityk_dir)) wxMkdir(fityk_dir); wxConfig::DontCreateOnDemand(); //prefix for wxConfig. It can be wxFileConfig or wxRegConfig, // so the prefix on MSW can't be absolute // On Unix - it is compatible with get_user_conffile() // On MSW - not compatible, but it uses registry, so it doesn't matter #ifdef __WXMAC__ wxString prefix = wxStandardPaths::Get().GetUserConfigDir() + wxFILE_SEP_PATH + wxT("pl.waw.unipress.fityk."); #else wxString prefix = pchar2wx(config_dirname) + wxFILE_SEP_PATH; #endif // set default and alternative config names conf_filename = prefix + wxT("config"); alt_conf_filename = prefix + wxT("alt-config"); // set config file for options automatically saved // it will be accessed only via wxConfig::Get() wxConfig *config = new wxConfig(wxT(""), wxT(""), prefix + wxT("wxoptions"), wxT(""), wxCONFIG_USE_LOCAL_FILE); wxConfig::Set(config); config_dir = get_user_conffile("configs") + wxFILE_SEP_PATH; if (!wxDirExists(config_dir)) wxMkdir(config_dir); DataEditorDlg::read_transforms(); // Create the main frame window frame = new FFrame(NULL, -1, wxT("fityk"), wxDEFAULT_FRAME_STYLE); wxConfigBase *cf; wxString g_config; if (cmdLineParser.Found(wxT("g"), &g_config)) cf = new wxFileConfig(wxT(""), wxT(""), config_dir + g_config, wxT(""), wxCONFIG_USE_LOCAL_FILE); else cf = new wxConfig(wxT(""), wxT(""), conf_filename, wxT(""), wxCONFIG_USE_LOCAL_FILE); frame->read_all_settings(cf); frame->plot_pane->set_mouse_mode(mmd_zoom); frame->Show(true); // it does not work earlier, problems with OutputWin colors (wxGTK gtk1.2) frame->io_pane->output_win->read_settings(cf); frame->io_pane->output_win->show_fancy_dashes(); // sash inside wxNoteBook can have wrong position (eg. wxGTK 2.7.1) frame->sidebar->read_settings(cf); delete cf; SetTopWindow(frame); if (!cmdLineParser.Found(wxT("I"))) { // run initial commands (from ~/.fityk/init file) wxString startup_file = get_user_conffile(startup_commands_filename); if (wxFileExists(startup_file)) { ftk->get_ui()->exec_script(wx2s(startup_file)); } } process_argv(cmdLineParser); frame->after_cmd_updates(); return true; } int FApp::OnExit() { delete ftk; wxConfig::Get()->Write(wxT("/FitykVersion"), pchar2wx(VERSION)); delete wxConfig::Set((wxConfig *) NULL); return 0; } namespace { struct less_filename : public binary_function { int n; less_filename(int n_) : n(n_) {} bool operator()(string x, string y) { if (isdigit(x[n]) && isdigit(y[n])) { string xc(x, n), yc(y, n); return strtod(xc.c_str(), 0) < strtod(yc.c_str(), 0); } else return x < y; } }; int find_common_prefix_length(vector const& p) { assert(p.size() > 1); for (size_t n = 0; n < p.begin()->size(); ++n) for (vector::const_iterator i = p.begin()+1; i != p.end(); ++i) if (n >= i->size() || (*i)[n] != (*p.begin())[n]) return n; return p.begin()->size(); } } // anonymous namespace /// parse and execute command line switches and arguments void FApp::process_argv(wxCmdLineParser &cmdLineParser) { wxString cmd; if (cmdLineParser.Found(wxT("c"), &cmd)) ftk->get_ui()->exec_and_log(wx2s(cmd)); //the rest of parameters/arguments are scripts and/or data files vector p; for (unsigned int i = 0; i < cmdLineParser.GetParamCount(); i++) p.push_back(wx2s(cmdLineParser.GetParam(i))); if (cmdLineParser.Found(wxT("r")) && p.size() > 1) { // reorder sort(p.begin(), p.end(), less_filename(find_common_prefix_length(p))); } for (vector::const_iterator i = p.begin(); i != p.end(); ++i) ftk->get_ui()->process_cmd_line_filename(*i); if (ftk->get_ds_count() > 1) { frame->SwitchSideBar(true); // zoom to show all loaded datafiles ftk->view.set_datasets(ftk->get_dsds()); ftk->view.fit(); } } #ifndef HELP_DIR # define HELP_DIR "." #endif //TODO when wx>=2.8 -> use GetResourcesDir() on all platforms string get_full_path_of_help_file (const string &name) { #ifdef __WXMAC__ return wx2s(wxStandardPaths::Get().GetResourcesDir() + wxFILE_SEP_PATH) + name; #else // filename --> path and filename // if there is no `name' file in HELP_DIR, we are trying a few other dirs wxString exedir = wxPathOnly(wxGetApp().argv[0]); if (!exedir.IsEmpty() && exedir.Last() != wxFILE_SEP_PATH) exedir += wxFILE_SEP_PATH; wxChar *possible_paths[] = { wxT(HELP_DIR), wxT("."), wxT(".."), wxT("doc"), wxT("../doc"), 0 }; for (int flag = 0; flag <= 1; ++flag) { for (int i = 0; possible_paths[i]; i++) { wxString path = !flag ? wxString(possible_paths[i]) : exedir + possible_paths[i]; if (!path.IsEmpty() && path.Last() != wxFILE_SEP_PATH) path += wxFILE_SEP_PATH; string path_name = wx2s(path) + name; //wxMessageBox(("Looking for \n" + path_name).c_str()); if (wxFileExists(s2wx(path_name))) return path_name; } } return name; #endif }