summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FL/Fl_Preferences.H9
-rw-r--r--fluid/Fd_Snap_Action.cxx14
-rw-r--r--fluid/Fd_Snap_Action.h21
-rw-r--r--fluid/Fl_Type.cxx9
-rw-r--r--fluid/README_fl.txt4
-rw-r--r--fluid/alignment_panel.cxx1329
-rw-r--r--fluid/alignment_panel.fl599
-rw-r--r--fluid/alignment_panel.h33
-rw-r--r--fluid/file.cxx55
-rw-r--r--fluid/fluid.cxx140
-rw-r--r--fluid/fluid.h33
-rw-r--r--fluid/pixmaps/fd_project.pngbin0 -> 6950 bytes
-rw-r--r--fluid/pixmaps/fd_user.pngbin0 -> 8612 bytes
-rw-r--r--fluid/shell_command.cxx832
-rw-r--r--fluid/shell_command.h100
-rw-r--r--fluid/sourceview_panel.cxx11
-rw-r--r--fluid/sourceview_panel.fl11
-rw-r--r--src/Fl_Preferences.cxx54
-rw-r--r--src/filename_absolute.cxx1
-rw-r--r--test/tree.fl6
-rw-r--r--test/unittest_core.cxx3
21 files changed, 2865 insertions, 399 deletions
diff --git a/FL/Fl_Preferences.H b/FL/Fl_Preferences.H
index 5f988a344..6aee47878 100644
--- a/FL/Fl_Preferences.H
+++ b/FL/Fl_Preferences.H
@@ -22,6 +22,7 @@
# include <stdio.h>
# include "Fl_Export.H"
+# include "fl_attr.h"
class Fl_String;
@@ -131,6 +132,7 @@ public:
ROOT_MASK = 0x00FF, ///< Mask for the values above
CORE = 0x0100, ///< OR'd by FLTK to read and write core library preferences and options
C_LOCALE = 0x1000, ///< This flag should always be set, it makes sure that floating point
+ CLEAR = 0x2000, ///< Don't read a possibly existing database. Instead, start with an empty set of preferences.
///< values are written correctly independently of the current locale
SYSTEM_L = SYSTEM | C_LOCALE, ///< Preferences are used system-wide, locale independent
USER_L = USER | C_LOCALE, ///< Preferences apply only to the current user, locale independent
@@ -188,7 +190,7 @@ public:
static Root filename( char *buffer, size_t buffer_size, Root root, const char *vendor, const char *application );
Fl_Preferences( Root root, const char *vendor, const char *application );
- Fl_Preferences( const char *path, const char *vendor, const char *application );
+ Fl_Preferences( const char *path, const char *vendor, const char *application, Root flags );
Fl_Preferences( Fl_Preferences &parent, const char *group );
Fl_Preferences( Fl_Preferences *parent, const char *group );
Fl_Preferences( Fl_Preferences &parent, int groupIndex );
@@ -197,6 +199,9 @@ public:
Fl_Preferences( ID id );
virtual ~Fl_Preferences();
+ FL_DEPRECATED("in 1.4.0 - use Fl_Preferences(path, vendor, application, flags) instead",
+ Fl_Preferences( const char *path, const char *vendor, const char *application ) );
+
Root filename( char *buffer, size_t buffer_size);
/** Return an ID that can later be reused to open more references to this dataset.
@@ -374,7 +379,7 @@ public: // older Sun compilers need this (public definition of the following cl
Root root_type_;
public:
RootNode( Fl_Preferences *, Root root, const char *vendor, const char *application );
- RootNode( Fl_Preferences *, const char *path, const char *vendor, const char *application );
+ RootNode( Fl_Preferences *, const char *path, const char *vendor, const char *application, Root flags );
RootNode( Fl_Preferences * );
~RootNode();
int read();
diff --git a/fluid/Fd_Snap_Action.cxx b/fluid/Fd_Snap_Action.cxx
index 3f52907ad..3602256f8 100644
--- a/fluid/Fd_Snap_Action.cxx
+++ b/fluid/Fd_Snap_Action.cxx
@@ -422,7 +422,7 @@ void Fd_Layout_Suite::init() {
name_ = NULL;
menu_label = NULL;
layout[0] = layout[1] = layout[2] = NULL;
- storage_ = 0;
+ storage_ = FD_STORE_INTERNAL;
}
/**
@@ -651,7 +651,7 @@ void Fd_Layout_List::update_menu_labels() {
*/
int Fd_Layout_List::load(const Fl_String &filename) {
remove_all(FD_STORE_FILE);
- Fl_Preferences prefs(filename.c_str(), "layout.fluid.fltk.org", NULL);
+ Fl_Preferences prefs(filename.c_str(), "layout.fluid.fltk.org", NULL, Fl_Preferences::C_LOCALE);
read(prefs, FD_STORE_FILE);
return 0;
}
@@ -661,7 +661,7 @@ int Fd_Layout_List::load(const Fl_String &filename) {
*/
int Fd_Layout_List::save(const Fl_String &filename) {
assert(this);
- Fl_Preferences prefs(filename.c_str(), "layout.fluid.fltk.org", NULL);
+ Fl_Preferences prefs(filename.c_str(), "layout.fluid.fltk.org", NULL, (Fl_Preferences::Root)(Fl_Preferences::C_LOCALE|Fl_Preferences::CLEAR));
prefs.clear();
write(prefs, FD_STORE_FILE);
return 0;
@@ -670,7 +670,7 @@ int Fd_Layout_List::save(const Fl_String &filename) {
/**
Write Suite and Layout selection and selected layout data to Preferences database.
*/
-void Fd_Layout_List::write(Fl_Preferences &prefs, int storage) {
+void Fd_Layout_List::write(Fl_Preferences &prefs, Fd_Tool_Store storage) {
Fl_Preferences prefs_list(prefs, "Layouts");
prefs_list.clear();
prefs_list.set("current_suite", list_[current_suite()].name_);
@@ -688,7 +688,7 @@ void Fd_Layout_List::write(Fl_Preferences &prefs, int storage) {
/**
Read Suite and Layout selection and selected layout data to Preferences database.
*/
-void Fd_Layout_List::read(Fl_Preferences &prefs, int storage) {
+void Fd_Layout_List::read(Fl_Preferences &prefs, Fd_Tool_Store storage) {
Fl_Preferences prefs_list(prefs, "Layouts");
Fl_String cs;
int cp = 0;
@@ -859,7 +859,7 @@ int Fd_Layout_List::add(const char *name) {
new_suite.layout[i] = new Fd_Layout_Preset;
::memcpy(new_suite.layout[i], old_suite.layout[i], sizeof(Fd_Layout_Preset));
}
- int new_storage = old_suite.storage_;
+ Fd_Tool_Store new_storage = old_suite.storage_;
if (new_storage == FD_STORE_INTERNAL)
new_storage = FD_STORE_USER;
new_suite.storage(new_storage);
@@ -904,7 +904,7 @@ void Fd_Layout_List::remove(int ix) {
Remove all Suites that use the given storage attribute.
\param[in] storage storage attribute, see FD_STORE_INTERNAL, etc.
*/
-void Fd_Layout_List::remove_all(int storage) {
+void Fd_Layout_List::remove_all(Fd_Tool_Store storage) {
for (int i=list_size_-1; i>=0; --i) {
if (list_[i].storage_ == storage)
remove(i);
diff --git a/fluid/Fd_Snap_Action.h b/fluid/Fd_Snap_Action.h
index 1355332a9..fefb4618f 100644
--- a/fluid/Fd_Snap_Action.h
+++ b/fluid/Fd_Snap_Action.h
@@ -17,6 +17,7 @@
#ifndef _FLUID_FD_SNAP_ACTION_H
#define _FLUID_FD_SNAP_ACTION_H
+#include "fluid.h"
#include "Fl_Window_Type.h"
#include <FL/Fl_String.H>
@@ -26,16 +27,6 @@ struct Fl_Menu_Item;
extern Fl_Menu_Item main_layout_submenu_[];
/**
- Indicate the storage location for a layout suite.
- */
-enum {
- FD_STORE_INTERNAL, ///< stored inside FLUID app
- FD_STORE_USER, ///< suite is stored in the user wide FLUID settings
- FD_STORE_PROJECT, ///< suite is stored within the current .fl project file
- FD_STORE_FILE ///< store suite in external file
-};
-
-/**
\brief Collection of layout settings.
Presets contain default fonts and font sizes for labels and text. They
@@ -97,13 +88,13 @@ public:
char *name_; ///< name of the suite
char *menu_label; ///< label text used in pulldown menu
Fd_Layout_Preset *layout[3]; ///< presets for application, dialog, and toolbox windows
- int storage_; ///< storage location (see FD_STORE_INTERNAL, etc.)
+ Fd_Tool_Store storage_; ///< storage location (see FD_STORE_INTERNAL, etc.)
void write(Fl_Preferences &prefs);
void read(Fl_Preferences &prefs);
void write(Fd_Project_Writer*);
void read(Fd_Project_Reader*);
void update_label();
- void storage(int s) { storage_ = s; update_label(); }
+ void storage(Fd_Tool_Store s) { storage_ = s; update_label(); }
void name(const char *n);
void init();
~Fd_Layout_Suite();
@@ -146,13 +137,13 @@ public:
int load(const Fl_String &filename);
int save(const Fl_String &filename);
- void write(Fl_Preferences &prefs, int storage);
- void read(Fl_Preferences &prefs, int storage);
+ void write(Fl_Preferences &prefs, Fd_Tool_Store storage);
+ void read(Fl_Preferences &prefs, Fd_Tool_Store storage);
void write(Fd_Project_Writer*);
void read(Fd_Project_Reader*);
int add(Fd_Layout_Suite*);
void remove(int index);
- void remove_all(int storage);
+ void remove_all(Fd_Tool_Store storage);
Fd_Layout_Preset *at(int);
int size();
};
diff --git a/fluid/Fl_Type.cxx b/fluid/Fl_Type.cxx
index d98db5883..379c4cb90 100644
--- a/fluid/Fl_Type.cxx
+++ b/fluid/Fl_Type.cxx
@@ -252,11 +252,16 @@ void delete_all(int selected_only) {
}
if(!selected_only) {
// reset the setting for the external shell command
- shell_prefs_get();
- shell_settings_write();
+ if (g_shell_config) {
+ g_shell_config->clear(FD_STORE_PROJECT);
+ g_shell_config->rebuild_shell_menu();
+ g_shell_config->update_settings_dialog();
+ }
widget_browser->hposition(0);
widget_browser->vposition(0);
g_layout_list.remove_all(FD_STORE_PROJECT);
+ g_layout_list.current_suite(0);
+ g_layout_list.current_preset(0);
g_layout_list.update_dialogs();
}
selection_changed(0);
diff --git a/fluid/README_fl.txt b/fluid/README_fl.txt
index 6cd14fe08..1845a1f12 100644
--- a/fluid/README_fl.txt
+++ b/fluid/README_fl.txt
@@ -444,6 +444,10 @@ Type "Fl_Widget" <word> : C++ variable name
"extra_code" <word> : C++ extra code lines
... : inherits more from Fl_Type
+Type "Fl_Button" <word> : C++ variable name
+
+ "compact" <word> : integer, set the flag for compact buttons, defaults to 0
+
Type "Fl_Flex" <word> : C++ variable name
"margins" <word> : this Word is written with printf as "{%d %d %d %d}",
diff --git a/fluid/alignment_panel.cxx b/fluid/alignment_panel.cxx
index 29f21fd4c..49348eb24 100644
--- a/fluid/alignment_panel.cxx
+++ b/fluid/alignment_panel.cxx
@@ -22,7 +22,61 @@
#include <FL/Fl_Tooltip.H>
#include <FL/fl_ask.H>
#include <string.h>
+#include "../src/flstring.h"
void scheme_cb(Fl_Scheme_Choice *, void *);
+int w_settings_shell_list_selected;
+
+Fl_Double_Window *script_panel=(Fl_Double_Window *)0;
+
+static void cb_script_panel(Fl_Double_Window*, void*) {
+ if (Fl::event()==FL_SHORTCUT && Fl::event_key()==FL_Escape)
+ return; // ignore Escape
+ script_panel->hide(); // otherwise hide..;
+}
+
+Fl_Text_Editor *script_input=(Fl_Text_Editor *)0;
+
+Fl_Return_Button *script_panel_ok=(Fl_Return_Button *)0;
+
+Fl_Button *script_panel_cancel=(Fl_Button *)0;
+
+Fl_Double_Window* make_script_panel() {
+ { Fl_Double_Window* o = script_panel = new Fl_Double_Window(540, 180, "Shell Script Editor");
+ script_panel->labelsize(11);
+ script_panel->callback((Fl_Callback*)cb_script_panel);
+ { script_input = new Fl_Text_Editor(10, 10, 520, 130);
+ script_input->box(FL_DOWN_BOX);
+ script_input->labelsize(11);
+ script_input->textfont(4);
+ script_input->textsize(11);
+ script_input->when(FL_WHEN_RELEASE | FL_WHEN_CHANGED | FL_WHEN_ENTER_KEY);
+ Fl_Group::current()->resizable(script_input);
+ script_input->buffer(new Fl_Text_Buffer);
+ } // Fl_Text_Editor* script_input
+ { Fl_Group* o = new Fl_Group(10, 150, 520, 20);
+ o->labelsize(11);
+ { script_panel_ok = new Fl_Return_Button(400, 150, 60, 20, "OK");
+ script_panel_ok->labelsize(11);
+ script_panel_ok->window()->hotspot(script_panel_ok);
+ } // Fl_Return_Button* script_panel_ok
+ { script_panel_cancel = new Fl_Button(470, 150, 60, 20, "Cancel");
+ script_panel_cancel->labelsize(11);
+ } // Fl_Button* script_panel_cancel
+ { Fl_Box* o = new Fl_Box(10, 150, 380, 20);
+ o->labelsize(11);
+ Fl_Group::current()->resizable(o);
+ } // Fl_Box* o
+ o->end();
+ } // Fl_Group* o
+ script_panel->set_modal();
+ o->size_range(200, 150);
+ script_panel->end();
+ } // Fl_Double_Window* script_panel
+ // Enable line numbers
+ script_input->linenumber_width(60);
+ script_input->linenumber_size(script_input->Fl_Text_Display::textsize());
+ return script_panel;
+}
Fl_Double_Window *settings_window=(Fl_Double_Window *)0;
@@ -755,63 +809,1089 @@ static Fl_Image *image_shell_64() {
return image;
}
-static void cb_Command(Fl_Input* o, void* v) {
+Fl_Browser *w_settings_shell_list=(Fl_Browser *)0;
+
+static void cb_w_settings_shell_list(Fl_Browser* o, void* v) {
if (v == LOAD) {
- o->value(g_shell_command.c_str());
+ // load from g_shell_config
+ if (g_shell_config) {
+ o->clear();
+ w_settings_shell_list_selected = 0;
+ for (int i=0; i<g_shell_config->list_size; i++) {
+ Fd_Shell_Command *cmd = g_shell_config->list[i];
+ o->add(cmd->name.c_str());
+ if (cmd->storage == FD_STORE_USER)
+ o->icon(i+1, w_settings_shell_fd_user->image());
+ else if (cmd->storage == FD_STORE_PROJECT)
+ o->icon(i+1, w_settings_shell_fd_project->image());
+ }
+ }
} else {
- g_shell_command = o->value();
+ // int prev_selected = w_settings_shell_list_selected;
+ w_settings_shell_list_selected = 0;
+ int selected = w_settings_shell_list->value();
+ if (selected) {
+ if (w_settings_shell_list->selected(selected))
+ w_settings_shell_list_selected = selected;
+ }
+ w_settings_shell_cmd->do_callback(w_settings_shell_cmd, LOAD);
+ w_settings_shell_toolbox->do_callback(w_settings_shell_toolbox, LOAD);
}
}
-static void cb_save(Fl_Check_Button* o, void* v) {
+Fl_Group *w_settings_shell_toolbox=(Fl_Group *)0;
+
+static void cb_w_settings_shell_toolbox(Fl_Group* o, void* v) {
+ if (v==LOAD) {
+ propagate_load(o, v);
+ }
+}
+
+static void cb_8(Fl_Button*, void* v) {
+ if (v != LOAD) {
+ int selected = w_settings_shell_list_selected;
+ Fd_Shell_Command *cmd = new Fd_Shell_Command("new shell command");
+ g_shell_config->insert(selected, cmd);
+ w_settings_shell_list->insert(selected+1, cmd->name.c_str());
+ w_settings_shell_list->deselect();
+ w_settings_shell_list->value(selected+1);
+ if (cmd->storage == FD_STORE_USER)
+ w_settings_shell_list->icon(selected+1, w_settings_shell_fd_user->image());
+ else if (cmd->storage == FD_STORE_PROJECT)
+ w_settings_shell_list->icon(selected+1, w_settings_shell_fd_project->image());
+ w_settings_shell_list->do_callback();
+ w_settings_shell_cmd->do_callback(w_settings_shell_cmd, LOAD);
+ w_settings_shell_toolbox->do_callback(w_settings_shell_toolbox, LOAD);
+ g_shell_config->rebuild_shell_menu();
+ }
+}
+
+Fl_Button *w_settings_shell_dup=(Fl_Button *)0;
+
+static void cb_w_settings_shell_dup(Fl_Button* o, void* v) {
+ int selected = w_settings_shell_list_selected;
+ if (v==LOAD) {
+ if (selected) {
+ o->activate();
+ } else {
+ o->deactivate();
+ }
+ } else {
+ if (!selected) return;
+ Fd_Shell_Command *cmd = new Fd_Shell_Command(g_shell_config->list[selected-1]);
+ g_shell_config->insert(selected, cmd);
+ w_settings_shell_list->insert(selected+1, cmd->name.c_str());
+ w_settings_shell_list->deselect();
+ w_settings_shell_list->deselect();
+ w_settings_shell_list->value(selected+1);
+ if (cmd->storage == FD_STORE_USER)
+ w_settings_shell_list->icon(selected+1, w_settings_shell_fd_user->image());
+ else if (cmd->storage == FD_STORE_PROJECT)
+ w_settings_shell_list->icon(selected+1, w_settings_shell_fd_project->image());
+ w_settings_shell_list->do_callback();
+ w_settings_shell_cmd->do_callback(w_settings_shell_cmd, LOAD);
+ w_settings_shell_toolbox->do_callback(w_settings_shell_toolbox, LOAD);
+ g_shell_config->rebuild_shell_menu();
+ }
+}
+
+Fl_Button *w_settings_shell_remove=(Fl_Button *)0;
+
+static void cb_w_settings_shell_remove(Fl_Button* o, void* v) {
+ int selected = w_settings_shell_list_selected;
+ if (v==LOAD) {
+ if (selected) {
+ o->activate();
+ } else {
+ o->deactivate();
+ }
+ } else {
+ if (!selected) return;
+ g_shell_config->remove(selected-1);
+ w_settings_shell_list->remove(selected);
+ if (selected <= w_settings_shell_list->size())
+ w_settings_shell_list->value(selected);
+ else
+ w_settings_shell_list->value(0);
+ w_settings_shell_list->do_callback();
+ w_settings_shell_cmd->do_callback(w_settings_shell_cmd, LOAD);
+ w_settings_shell_toolbox->do_callback(w_settings_shell_toolbox, LOAD);
+ g_shell_config->rebuild_shell_menu();
+ }
+}
+
+Fl_Menu_Button *w_settings_shell_menu=(Fl_Menu_Button *)0;
+
+static void cb_Import(Fl_Menu_*, void* v) {
+ if (v != LOAD)
+ Fd_Shell_Command_List::import_from_file();
+}
+
+static void cb_Export(Fl_Menu_*, void* v) {
+ if (v != LOAD)
+ Fd_Shell_Command_List::export_selected();
+}
+
+Fl_Menu_Item menu_w_settings_shell_menu[] = {
+ {"Import...", 0, (Fl_Callback*)cb_Import, 0, 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0},
+ {"Export selected...", 0, (Fl_Callback*)cb_Export, 0, 128, (uchar)FL_NORMAL_LABEL, 0, 11, 0},
+ {"Import Example Scripts:", 0, 0, 0, 1, (uchar)FL_NORMAL_LABEL, 1, 10, 0},
+ {"Compile with fltk-config", 0, 0, 0, 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0},
+ {"Build and run", 0, 0, 0, 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0},
+ {"Build with Xcode on macOS", 0, 0, 0, 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0},
+ {"Build with CMake", 0, 0, 0, 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0},
+ {0,0,0,0,0,0,0,0,0}
+};
+
+Fl_Button *w_settings_shell_play=(Fl_Button *)0;
+
+static void cb_w_settings_shell_play(Fl_Button* o, void* v) {
+ int selected = w_settings_shell_list_selected;
+ if (v==LOAD) {
+ if (selected) {
+ o->activate();
+ } else {
+ o->deactivate();
+ }
+ } else {
+ if (!selected) return;
+ Fd_Shell_Command *cmd = g_shell_config->list[selected-1];
+ cmd->run();
+ }
+}
+
+Fl_Group *w_settings_shell_cmd=(Fl_Group *)0;
+
+static void cb_w_settings_shell_cmd(Fl_Group* o, void* v) {
+ if (v==LOAD) {
+ int selected = w_settings_shell_list_selected;
+ if (selected) {
+ o->activate();
+ } else {
+ o->deactivate();
+ }
+ propagate_load(o, v);
+ }
+}
+
+static void cb_Name(Fl_Input* o, void* v) {
+ int selected = w_settings_shell_list_selected;
if (v == LOAD) {
- o->value(g_shell_save_fl);
+ if (selected) {
+ o->value(g_shell_config->list[selected-1]->name.c_str());
+ } else {
+ o->value("");
+ }
} else {
- g_shell_save_fl = o->value();
+ if (selected) {
+ Fd_Shell_Command *cmd = g_shell_config->list[selected-1];
+ cmd->name = o->value();
+ w_settings_shell_list->text(selected, o->value());
+ if (cmd->storage == FD_STORE_PROJECT) set_modflag(1);
+ }
}
}
-static void cb_save1(Fl_Check_Button* o, void* v) {
+static void cb_Label(Fl_Input* o, void* v) {
+ int selected = w_settings_shell_list_selected;
if (v == LOAD) {
- o->value(g_shell_save_code);
+ if (selected) {
+ o->value(g_shell_config->list[selected-1]->label.c_str());
+ } else {
+ o->value("");
+ }
} else {
- g_shell_save_code = o->value();
+ if (selected) {
+ Fd_Shell_Command *cmd = g_shell_config->list[selected-1];
+ cmd->label = o->value();
+ cmd->update_shell_menu();
+ if (cmd->storage == FD_STORE_PROJECT) set_modflag(1);
+ }
}
}
-static void cb_save2(Fl_Check_Button* o, void* v) {
+static void cb_Shortcut(Fl_Shortcut_Button* o, void* v) {
+ int selected = w_settings_shell_list_selected;
if (v == LOAD) {
- o->value(g_shell_save_strings);
+ if (selected) {
+ o->value(g_shell_config->list[selected-1]->shortcut);
+ o->default_value(o->value());
+ } else {
+ o->value(0);
+ }
+ } else {
+ if (selected) {
+ Fd_Shell_Command *cmd = g_shell_config->list[selected-1];
+ cmd->shortcut = o->value();
+ cmd->update_shell_menu();
+ if (cmd->storage == FD_STORE_PROJECT) set_modflag(1);
+ }
+ }
+}
+
+static void cb_Store(Fl_Choice* o, void* v) {
+ int selected = w_settings_shell_list_selected;
+ if (v == LOAD) {
+ if (selected) {
+ Fd_Tool_Store ts = g_shell_config->list[selected-1]->storage;
+ o->value(o->find_item_with_argument((long)ts));
+ } else {
+ o->value(o->find_item_with_argument((long)FD_STORE_USER));
+ }
} else {
- g_shell_save_strings = o->value();
+ if (selected) {
+ Fd_Shell_Command *cmd = g_shell_config->list[selected-1];
+ Fd_Tool_Store ts = (Fd_Tool_Store)(o->mvalue()->argument());
+ if (cmd->storage == FD_STORE_PROJECT) set_modflag(1);
+ cmd->storage = ts;
+ //w_settings_shell_list->text(selected, cmd->name.c_str());
+ if (cmd->storage == FD_STORE_USER)
+ w_settings_shell_list->icon(selected, w_settings_shell_fd_user->image());
+ else if (cmd->storage == FD_STORE_PROJECT)
+ w_settings_shell_list->icon(selected, w_settings_shell_fd_project->image());
+ if (cmd->storage == FD_STORE_PROJECT) set_modflag(1);
+ }
}
}
-Fl_Check_Button *shell_use_fl_button=(Fl_Check_Button *)0;
+Fl_Menu_Item menu_Store[] = {
+ {"@fd_user User Setting", 0, 0, (void*)(FD_STORE_USER), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0},
+ {"@fd_project Project File", 0, 0, (void*)(FD_STORE_PROJECT), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0},
+ {0,0,0,0,0,0,0,0,0}
+};
-static void cb_shell_use_fl_button(Fl_Check_Button* o, void* v) {
+static void cb_Condition(Fl_Choice* o, void* v) {
+ int selected = w_settings_shell_list_selected;
if (v == LOAD) {
- o->value(g_shell_use_fl_settings);
+ if (selected) {
+ int cond = g_shell_config->list[selected-1]->condition;
+ o->value(o->find_item_with_argument(cond));
+ } else {
+ o->value(o->find_item_with_argument(0));
+ }
} else {
- g_shell_use_fl_settings = o->value();
- fluid_prefs.set("shell_use_fl", g_shell_use_fl_settings);
- if (g_shell_use_fl_settings) {
- shell_settings_read();
+ if (selected) {
+ Fd_Shell_Command *cmd = g_shell_config->list[selected-1];
+ int cond = (int)(o->mvalue()->argument());
+ cmd->condition = cond;
+ g_shell_config->rebuild_shell_menu();
+ if (cmd->storage == FD_STORE_PROJECT) set_modflag(1);
+ }
+ }
+}
+
+Fl_Menu_Item menu_Condition[] = {
+ {"all platforms", 0, 0, (void*)(Fd_Shell_Command::ALWAYS), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0},
+ {"MS Windows only", 0, 0, (void*)(Fd_Shell_Command::WIN_ONLY), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0},
+ {"Linux only", 0, 0, (void*)(Fd_Shell_Command::UX_ONLY), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0},
+ {"macOS only", 0, 0, (void*)(Fd_Shell_Command::MAC_ONLY), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0},
+ {"Linux and macOS", 0, 0, (void*)(Fd_Shell_Command::MAC_AND_UX_ONLY), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0},
+ {"don\'t use", 0, 0, (void*)(Fd_Shell_Command::NEVER), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0},
+ {0,0,0,0,0,0,0,0,0}
+};
+
+static void cb_Label1(Fl_Input* o, void* v) {
+ if (v == LOAD) {
+ // o->value(g_shell_command.c_str());
+ } else {
+ // g_shell_command = o->value();
+ }
+}
+
+Fl_Text_Editor *w_settings_shell_command=(Fl_Text_Editor *)0;
+
+static void cb_w_settings_shell_command(Fl_Text_Editor* o, void* v) {
+ int selected = w_settings_shell_list_selected;
+ if (v == LOAD) {
+ if (selected) {
+ o->buffer()->text(g_shell_config->list[selected-1]->command.c_str());
} else {
- shell_prefs_get();
+ o->buffer()->text("");
+ }
+ } else {
+ if (selected) {
+ Fd_Shell_Command *cmd = g_shell_config->list[selected-1];
+ cmd->command = o->buffer()->text();
+ if (cmd->storage == FD_STORE_PROJECT) set_modflag(1);
}
- w_settings_shell_tab->do_callback(w_settings_shell_tab, LOAD);
}
}
-static void cb_save3(Fl_Button*, void* v) {
- if (v != LOAD)
- shell_prefs_set();
+Fl_Menu_Button *w_settings_shell_text_macros=(Fl_Menu_Button *)0;
+
+static void cb_w_settings_shell_text_macros(Fl_Menu_Button* o, void*) {
+ const Fl_Menu_Item *mi = o->mvalue();
+ if (mi) {
+ char buffer[256];
+ fl_strlcpy(buffer, mi->label(), 255);
+ int n = (int)strlen(buffer)-1;
+ if (buffer[n]=='@') buffer[n] = 0;
+ char *word = buffer;
+ if (word[0]=='@') word++;
+ if (w_settings_shell_command->buffer()->selected()) {
+ int start = 0, end = 0;
+ w_settings_shell_command->buffer()->selection_position(&start, &end);
+ w_settings_shell_command->buffer()->replace(start, end, word);
+ } else {
+ int pos = w_settings_shell_command->insert_position();
+ w_settings_shell_command->buffer()->insert(pos, word);
+ }
+ w_settings_shell_command->do_callback(w_settings_shell_command, (void*)NULL);
+ }
+}
+
+Fl_Menu_Item menu_w_settings_shell_text_macros[] = {
+ {"@@BASENAME@@", 0, 0, 0, 0, (uchar)FL_NORMAL_LABEL, 4, 11, 0},
+ {"@@PROJECTFILE_PATH@@", 0, 0, 0, 0, (uchar)FL_NORMAL_LABEL, 4, 11, 0},
+ {"@@PROJECTFILE_NAME@@", 0, 0, 0, 0, (uchar)FL_NORMAL_LABEL, 4, 11, 0},
+ {"@@CODEFILE_PATH@@", 0, 0, 0, 0, (uchar)FL_NORMAL_LABEL, 4, 11, 0},
+ {"@@CODEFILE_NAME@@", 0, 0, 0, 0, (uchar)FL_NORMAL_LABEL, 4, 11, 0},
+ {"@@HEADERFILE_PATH@@", 0, 0, 0, 0, (uchar)FL_NORMAL_LABEL, 4, 11, 0},
+ {"@@HEADERFILE_NAME@@", 0, 0, 0, 0, (uchar)FL_NORMAL_LABEL, 4, 11, 0},
+ {"@@TEXTFILE_PATH@@", 0, 0, 0, 0, (uchar)FL_NORMAL_LABEL, 4, 11, 0},
+ {"@@TEXTFILE_NAME@@", 0, 0, 0, 0, (uchar)FL_NORMAL_LABEL, 4, 11, 0},
+ // Not yet implemented
+ {"@@FLTK_CONFIG@@", 0, 0, 0, 16, (uchar)FL_NORMAL_LABEL, 4, 11, 0},
+ {"@@TMPDIR@@", 0, 0, 0, 0, (uchar)FL_NORMAL_LABEL, 4, 11, 0},
+ {0,0,0,0,0,0,0,0,0}
+};
+
+static void cb_square(Fl_Button*, void*) {
+ if (!script_panel) make_script_panel();
+ script_input->buffer()->text(w_settings_shell_command->buffer()->text());
+ script_panel->show();
+
+ for (;;) {
+ Fl_Widget* w = Fl::readqueue();
+ if (w == script_panel_cancel) goto BREAK2;
+ else if (w == script_panel_ok) break;
+ else if (!w) Fl::wait();
+ }
+
+ w_settings_shell_command->buffer()->text(script_input->buffer()->text());
+ w_settings_shell_command->do_callback();
+ BREAK2:
+ script_panel->hide();
+}
+
+static void cb_save(Fl_Check_Button* o, void* v) {
+ int selected = w_settings_shell_list_selected;
+ if (v == LOAD) {
+ if (selected) {
+ o->value(g_shell_config->list[selected-1]->flags & Fd_Shell_Command::SAVE_PROJECT);
+ } else {
+ o->value(0);
+ }
+ } else {
+ if (selected) {
+ Fd_Shell_Command *cmd = g_shell_config->list[selected-1];
+ int v = o->value();
+ if (v) {
+ cmd->flags |= Fd_Shell_Command::SAVE_PROJECT;
+ } else {
+ cmd->flags &= ~Fd_Shell_Command::SAVE_PROJECT;
+ }
+ if (cmd->storage == FD_STORE_PROJECT) set_modflag(1);
+ }
+ }
+}
+
+static void cb_save1(Fl_Check_Button* o, void* v) {
+ int selected = w_settings_shell_list_selected;
+ if (v == LOAD) {
+ if (selected) {
+ o->value(g_shell_config->list[selected-1]->flags & Fd_Shell_Command::SAVE_SOURCECODE);
+ } else {
+ o->value(0);
+ }
+ } else {
+ if (selected) {
+ Fd_Shell_Command *cmd = g_shell_config->list[selected-1];
+ int v = o->value();
+ if (v) {
+ cmd->flags |= Fd_Shell_Command::SAVE_SOURCECODE;
+ } else {
+ cmd->flags &= ~Fd_Shell_Command::SAVE_SOURCECODE;
+ }
+ if (cmd->storage == FD_STORE_PROJECT) set_modflag(1);
+ }
+ }
+}
+
+static void cb_save2(Fl_Check_Button* o, void* v) {
+ int selected = w_settings_shell_list_selected;
+ if (v == LOAD) {
+ if (selected) {
+ o->value(g_shell_config->list[selected-1]->flags & Fd_Shell_Command::SAVE_STRINGS);
+ } else {
+ o->value(0);
+ }
+ } else {
+ if (selected) {
+ Fd_Shell_Command *cmd = g_shell_config->list[selected-1];
+ int v = o->value();
+ if (v) {
+ cmd->flags |= Fd_Shell_Command::SAVE_STRINGS;
+ } else {
+ cmd->flags &= ~Fd_Shell_Command::SAVE_STRINGS;
+ }
+ if (cmd->storage == FD_STORE_PROJECT) set_modflag(1);
+ }
+ }
+}
+
+Fl_Box *w_settings_shell_fd_project=(Fl_Box *)0;
+
+static const unsigned char idata_fd_project[] =
+{137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0,0,
+115,122,122,244,0,0,1,110,105,67,67,80,105,99,99,0,0,40,145,117,145,187,75,195,
+80,20,198,127,173,239,23,14,58,136,116,200,80,197,65,65,20,196,81,235,208,165,
+72,169,21,172,186,180,49,109,133,164,13,73,139,136,171,224,226,80,112,16,93,
+124,13,254,7,186,10,174,10,130,160,8,34,110,238,190,22,145,120,174,45,180,136,
+189,225,230,252,248,238,253,14,39,95,192,31,49,117,203,109,156,2,43,87,112,98,
+225,144,182,144,88,212,90,94,104,163,153,46,2,244,39,117,215,158,142,70,35,212,
+93,159,119,248,84,189,29,81,189,234,223,251,119,117,172,24,174,14,190,86,225,9,
+221,118,10,194,50,13,145,181,130,173,120,91,184,87,207,38,87,132,15,133,135,29,
+25,80,248,74,233,169,50,63,43,206,148,249,93,177,19,143,205,128,95,245,212,50,
+53,156,170,97,61,235,88,194,67,194,65,203,44,234,149,121,212,151,116,26,185,
+249,57,169,253,178,3,184,196,8,19,66,35,69,145,85,76,10,140,72,205,73,102,255,
+251,70,127,125,179,228,197,163,203,219,102,29,71,28,25,178,226,29,22,181,40,93,
+13,169,105,209,13,121,76,214,85,238,127,243,116,211,227,99,229,238,157,33,104,
+122,242,188,183,1,104,217,129,239,146,231,125,29,121,222,247,49,52,60,194,69,
+174,234,207,75,78,147,31,162,151,170,90,240,0,186,55,225,236,178,170,165,118,
+225,124,11,250,30,236,164,147,252,149,26,100,251,211,105,120,61,133,174,4,244,
+220,64,251,82,57,171,202,57,39,247,16,223,144,95,116,13,123,251,48,40,247,187,
+151,127,0,229,44,103,253,189,250,32,75,0,0,0,9,112,72,89,115,0,0,22,37,0,0,22,
+37,1,73,82,36,240,0,0,1,13,116,69,88,116,82,97,119,32,112,114,111,102,105,108,
+101,32,116,121,112,101,32,101,120,105,102,0,10,101,120,105,102,10,32,32,32,32,
+32,49,49,52,10,52,53,55,56,54,57,54,54,48,48,48,48,52,57,52,57,50,97,48,48,48,
+56,48,48,48,48,48,48,48,52,48,48,49,97,48,49,48,53,48,48,48,49,48,48,48,48,48,
+48,51,101,48,48,48,48,48,48,49,98,48,49,48,53,48,48,48,49,48,48,48,48,48,48,10,
+52,54,48,48,48,48,48,48,50,56,48,49,48,51,48,48,48,49,48,48,48,48,48,48,48,50,
+48,48,48,48,48,48,54,57,56,55,48,52,48,48,48,49,48,48,48,48,48,48,52,101,48,48,
+48,48,48,48,48,48,48,48,48,48,48,48,57,48,48,48,48,48,48,48,10,48,49,48,48,48,
+48,48,48,57,48,48,48,48,48,48,48,48,49,48,48,48,48,48,48,48,50,48,48,48,50,97,
+48,48,52,48,48,48,49,48,48,48,48,48,48,53,50,48,48,48,48,48,48,48,51,97,48,48,
+52,48,48,48,49,48,48,48,48,48,48,56,48,48,48,10,48,48,48,48,48,48,48,48,48,48,
+48,48,10,190,225,144,105,0,0,0,90,116,69,88,116,82,97,119,32,112,114,111,102,
+105,108,101,32,116,121,112,101,32,105,112,116,99,0,10,105,112,116,99,10,32,32,
+32,32,32,32,50,54,10,53,48,54,56,54,102,55,52,54,102,55,51,54,56,54,102,55,48,
+50,48,51,51,50,101,51,48,48,48,51,56,52,50,52,57,52,100,48,52,48,52,48,48,48,
+48,48,48,48,48,48,48,48,48,10,199,209,105,220,0,0,20,96,116,69,88,116,82,97,
+119,32,112,114,111,102,105,108,101,32,116,121,112,101,32,120,109,112,0,10,120,
+109,112,10,32,32,32,32,50,53,53,53,10,51,99,51,102,55,56,55,48,54,49,54,51,54,
+98,54,53,55,52,50,48,54,50,54,53,54,55,54,57,54,101,51,100,50,50,101,102,98,98,
+98,102,50,50,50,48,54,57,54,52,51,100,50,50,53,55,51,53,52,100,51,48,52,100,55,
+48,52,51,54,53,54,56,54,57,10,52,56,55,97,55,50,54,53,53,51,55,97,52,101,53,52,
+54,51,55,97,54,98,54,51,51,57,54,52,50,50,51,102,51,101,48,97,51,99,55,56,51,
+97,55,56,54,100,55,48,54,100,54,53,55,52,54,49,50,48,55,56,54,100,54,99,54,101,
+55,51,51,97,55,56,10,51,100,50,50,54,49,54,52,54,102,54,50,54,53,51,97,54,101,
+55,51,51,97,54,100,54,53,55,52,54,49,50,102,50,50,50,48,55,56,51,97,55,56,54,
+100,55,48,55,52,54,98,51,100,50,50,53,56,52,100,53,48,50,48,52,51,54,102,55,50,
+54,53,50,48,10,51,52,50,101,51,52,50,101,51,48,50,100,52,53,55,56,54,57,55,54,
+51,50,50,50,51,101,48,97,50,48,51,99,55,50,54,52,54,54,51,97,53,50,52,52,52,54,
+50,48,55,56,54,100,54,99,54,101,55,51,51,97,55,50,54,52,54,54,51,100,50,50,54,
+56,10,55,52,55,52,55,48,51,97,50,102,50,102,55,55,55,55,55,55,50,101,55,55,51,
+51,50,101,54,102,55,50,54,55,50,102,51,49,51,57,51,57,51,57,50,102,51,48,51,50,
+50,102,51,50,51,50,50,100,55,50,54,52,54,54,50,100,55,51,55,57,54,101,55,52,10,
+54,49,55,56,50,100,54,101,55,51,50,51,50,50,51,101,48,97,50,48,50,48,51,99,55,
+50,54,52,54,54,51,97,52,52,54,53,55,51,54,51,55,50,54,57,55,48,55,52,54,57,54,
+102,54,101,50,48,55,50,54,52,54,54,51,97,54,49,54,50,54,102,55,53,10,55,52,51,
+100,50,50,50,50,48,97,50,48,50,48,50,48,50,48,55,56,54,100,54,99,54,101,55,51,
+51,97,54,53,55,56,54,57,54,54,51,100,50,50,54,56,55,52,55,52,55,48,51,97,50,
+102,50,102,54,101,55,51,50,101,54,49,54,52,54,102,54,50,54,53,10,50,101,54,51,
+54,102,54,100,50,102,54,53,55,56,54,57,54,54,50,102,51,49,50,101,51,48,50,102,
+50,50,48,97,50,48,50,48,50,48,50,48,55,56,54,100,54,99,54,101,55,51,51,97,55,
+52,54,57,54,54,54,54,51,100,50,50,54,56,55,52,55,52,55,48,10,51,97,50,102,50,
+102,54,101,55,51,50,101,54,49,54,52,54,102,54,50,54,53,50,101,54,51,54,102,54,
+100,50,102,55,52,54,57,54,54,54,54,50,102,51,49,50,101,51,48,50,102,50,50,48,97,
+50,48,50,48,50,48,54,53,55,56,54,57,54,54,51,97,53,48,10,54,57,55,56,54,53,54,
+99,53,56,52,52,54,57,54,100,54,53,54,101,55,51,54,57,54,102,54,101,51,100,50,
+50,51,56,51,50,50,50,48,97,50,48,50,48,50,48,54,53,55,56,54,57,54,54,51,97,53,
+48,54,57,55,56,54,53,54,99,53,57,52,52,54,57,10,54,100,54,53,54,101,55,51,54,
+57,54,102,54,101,51,100,50,50,51,49,51,50,51,56,50,50,48,97,50,48,50,48,50,48,
+55,52,54,57,54,54,54,54,51,97,53,50,54,53,55,51,54,102,54,99,55,53,55,52,54,57,
+54,102,54,101,53,53,54,101,54,57,55,52,10,51,100,50,50,51,50,50,50,48,97,50,48,
+50,48,50,48,55,52,54,57,54,54,54,54,51,97,53,57,53,50,54,53,55,51,54,102,54,99,
+55,53,55,52,54,57,54,102,54,101,51,100,50,50,51,49,51,52,51,52,50,48,50,102,50,
+48,51,49,50,50,48,97,50,48,10,50,48,50,48,55,52,54,57,54,54,54,54,51,97,53,56,
+53,50,54,53,55,51,54,102,54,99,55,53,55,52,54,57,54,102,54,101,51,100,50,50,51,
+49,51,52,51,52,50,48,50,102,50,48,51,49,50,50,50,102,51,101,48,97,50,48,51,99,
+50,102,55,50,54,52,10,54,54,51,97,53,50,52,52,52,54,51,101,48,97,51,99,50,102,
+55,56,51,97,55,56,54,100,55,48,54,100,54,53,55,52,54,49,51,101,48,97,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,48,97,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,48,97,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,48,97,50,48,10,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,48,97,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,48,97,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,48,97,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,48,
+97,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,48,97,10,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,48,97,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,48,97,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,48,97,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,48,97,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,10,48,97,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,48,97,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,48,
+97,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,48,97,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,48,97,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,48,97,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,48,97,50,48,50,48,50,48,50,48,50,48,10,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,48,97,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,48,97,51,99,51,102,55,56,55,48,54,49,
+54,51,54,98,54,53,55,52,50,48,54,53,54,101,54,52,51,100,50,50,55,55,50,50,51,
+102,51,101,10,87,123,188,247,0,0,3,115,73,68,65,84,88,71,189,151,75,75,91,65,20,
+199,79,110,222,169,52,180,203,22,186,239,210,47,80,236,206,126,5,177,17,151,46,
+68,23,82,220,138,90,84,116,163,184,80,81,132,98,93,234,42,203,210,79,209,149,
+32,213,68,164,165,165,129,230,97,94,246,252,166,157,246,246,102,154,132,230,
+226,31,134,59,247,204,153,243,158,123,207,68,206,206,206,164,86,171,73,52,26,
+149,68,34,17,175,84,42,215,123,123,123,15,119,118,118,164,23,26,141,134,164,211,
+105,243,28,29,29,149,229,229,229,183,177,88,236,101,171,213,106,235,83,154,205,
+166,120,158,39,145,72,196,12,23,188,106,181,42,201,100,82,110,111,111,69,149,55,
+246,247,247,139,187,187,187,102,209,110,252,215,200,100,50,162,202,12,111,62,
+159,151,211,211,211,49,85,252,70,135,231,212,230,64,44,149,74,201,205,205,141,
+196,227,113,97,174,222,84,48,102,102,102,70,230,230,230,186,110,110,183,219,178,
+177,177,33,219,219,219,198,129,133,133,5,188,30,27,31,31,71,78,78,89,90,93,5,40,
+60,60,32,92,8,168,215,235,120,86,96,129,148,244,138,0,70,219,208,142,140,140,
+144,66,89,89,89,145,163,163,163,49,221,255,90,195,31,65,62,60,200,7,240,48,39,
+53,198,0,187,96,94,126,230,43,195,28,239,122,129,189,150,111,120,120,88,22,23,
+23,13,109,105,105,73,142,143,143,95,169,242,247,42,51,107,249,144,79,202,49,
+136,186,1,198,0,191,17,186,88,177,194,123,1,239,134,134,134,76,228,152,79,78,78,
+202,250,250,186,137,232,218,218,154,156,156,156,60,211,72,92,43,235,115,60,247,
+43,166,238,128,137,67,192,136,102,183,170,245,3,30,45,92,227,25,74,121,78,76,
+76,152,72,112,2,168,137,195,195,195,148,210,223,169,226,23,208,40,92,210,203,
+201,3,158,205,15,33,98,232,60,101,22,188,222,133,108,235,135,90,64,40,239,200,
+154,154,154,50,17,96,190,185,185,73,77,80,224,121,93,127,130,62,12,97,15,48,6,
+88,101,254,72,244,19,1,194,138,48,242,74,26,108,152,145,145,203,229,76,65,226,
+212,234,234,170,28,28,28,96,228,71,235,168,69,44,24,110,221,156,237,39,255,22,
+40,197,155,173,173,45,115,36,153,147,22,66,205,241,198,57,140,164,54,74,165,82,
+99,122,122,250,47,71,141,235,129,40,164,131,133,249,47,16,242,96,85,227,29,133,
+201,187,149,107,63,116,58,10,24,131,209,22,158,221,4,51,2,117,67,201,127,110,
+187,1,190,249,249,121,185,188,188,148,98,177,40,87,87,87,102,126,126,126,110,
+230,133,66,65,46,46,46,100,118,118,214,242,127,192,32,127,10,92,149,246,217,65,
+11,11,159,130,4,151,1,53,7,45,44,60,8,18,92,6,60,114,208,194,66,35,72,112,25,
+80,113,208,194,66,50,72,112,25,240,205,65,11,11,55,65,194,93,167,160,175,8,68,
+29,180,176,224,142,0,103,211,254,163,245,140,86,59,247,253,31,252,95,216,95,
+243,108,144,199,21,129,14,166,16,113,63,72,112,25,80,119,208,194,194,215,32,193,
+101,64,104,41,112,160,28,36,220,117,10,238,5,9,119,157,130,14,125,46,3,254,252,
+43,195,71,51,72,112,25,240,197,65,11,11,29,245,229,217,179,106,155,10,237,104,
+154,253,180,228,253,2,153,246,142,161,207,36,223,26,123,155,2,30,139,86,33,237,
+148,246,118,41,255,197,97,16,160,148,238,135,214,140,161,198,52,81,110,47,39,
+224,119,71,196,176,157,45,253,28,173,211,160,176,109,25,45,25,50,213,193,199,
+190,27,152,225,137,209,159,99,17,30,151,203,101,218,236,44,52,154,76,90,234,65,
+128,34,228,250,90,246,136,255,29,196,176,206,118,175,58,79,232,226,83,24,236,
+213,122,16,176,223,94,207,73,175,70,249,59,81,177,117,128,158,31,49,127,246,30,
+207,181,170,20,0,0,0,0,73,69,78,68,174,66,96,130};
+static Fl_Image *image_fd_project() {
+ static Fl_Image *image = NULL;
+ if (!image)
+ image = new Fl_PNG_Image("fd_project.png", idata_fd_project, 6950);
+ return image;
}
-static void cb_Run(Fl_Return_Button*, void* v) {
- if (v != LOAD)
- do_shell_command(NULL, NULL);
+Fl_Box *w_settings_shell_fd_user=(Fl_Box *)0;
+
+static const unsigned char idata_fd_user[] =
+{137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0,0,
+115,122,122,244,0,0,1,110,105,67,67,80,105,99,99,0,0,40,145,117,145,187,75,195,
+80,20,198,127,173,239,23,14,58,136,116,200,80,197,65,65,20,196,81,235,208,165,
+72,169,21,172,186,180,49,109,133,164,13,73,139,136,171,224,226,80,112,16,93,
+124,13,254,7,186,10,174,10,130,160,8,34,110,238,190,22,145,120,174,45,180,136,
+189,225,230,252,248,238,253,14,39,95,192,31,49,117,203,109,156,2,43,87,112,98,
+225,144,182,144,88,212,90,94,104,163,153,46,2,244,39,117,215,158,142,70,35,212,
+93,159,119,248,84,189,29,81,189,234,223,251,119,117,172,24,174,14,190,86,225,9,
+221,118,10,194,50,13,145,181,130,173,120,91,184,87,207,38,87,132,15,133,135,29,
+25,80,248,74,233,169,50,63,43,206,148,249,93,177,19,143,205,128,95,245,212,50,
+53,156,170,97,61,235,88,194,67,194,65,203,44,234,149,121,212,151,116,26,185,
+249,57,169,253,178,3,184,196,8,19,66,35,69,145,85,76,10,140,72,205,73,102,255,
+251,70,127,125,179,228,197,163,203,219,102,29,71,28,25,178,226,29,22,181,40,93,
+13,169,105,209,13,121,76,214,85,238,127,243,116,211,227,99,229,238,157,33,104,
+122,242,188,183,1,104,217,129,239,146,231,125,29,121,222,247,49,52,60,194,69,
+174,234,207,75,78,147,31,162,151,170,90,240,0,186,55,225,236,178,170,165,118,
+225,124,11,250,30,236,164,147,252,149,26,100,251,211,105,120,61,133,174,4,244,
+220,64,251,82,57,171,202,57,39,247,16,223,144,95,116,13,123,251,48,40,247,187,
+151,127,0,229,44,103,253,189,250,32,75,0,0,0,9,112,72,89,115,0,0,22,37,0,0,22,
+37,1,73,82,36,240,0,0,1,13,116,69,88,116,82,97,119,32,112,114,111,102,105,108,
+101,32,116,121,112,101,32,101,120,105,102,0,10,101,120,105,102,10,32,32,32,32,
+32,49,49,52,10,52,53,55,56,54,57,54,54,48,48,48,48,52,57,52,57,50,97,48,48,48,
+56,48,48,48,48,48,48,48,52,48,48,49,97,48,49,48,53,48,48,48,49,48,48,48,48,48,
+48,51,101,48,48,48,48,48,48,49,98,48,49,48,53,48,48,48,49,48,48,48,48,48,48,10,
+52,54,48,48,48,48,48,48,50,56,48,49,48,51,48,48,48,49,48,48,48,48,48,48,48,50,
+48,48,48,48,48,48,54,57,56,55,48,52,48,48,48,49,48,48,48,48,48,48,52,101,48,48,
+48,48,48,48,48,48,48,48,48,48,48,48,57,48,48,48,48,48,48,48,10,48,49,48,48,48,
+48,48,48,57,48,48,48,48,48,48,48,48,49,48,48,48,48,48,48,48,50,48,48,48,50,97,
+48,48,52,48,48,48,49,48,48,48,48,48,48,53,50,48,48,48,48,48,48,48,51,97,48,48,
+52,48,48,48,49,48,48,48,48,48,48,56,48,48,48,10,48,48,48,48,48,48,48,48,48,48,
+48,48,10,190,225,144,105,0,0,0,90,116,69,88,116,82,97,119,32,112,114,111,102,
+105,108,101,32,116,121,112,101,32,105,112,116,99,0,10,105,112,116,99,10,32,32,
+32,32,32,32,50,54,10,53,48,54,56,54,102,55,52,54,102,55,51,54,56,54,102,55,48,
+50,48,51,51,50,101,51,48,48,48,51,56,52,50,52,57,52,100,48,52,48,52,48,48,48,
+48,48,48,48,48,48,48,48,48,10,199,209,105,220,0,0,20,96,116,69,88,116,82,97,
+119,32,112,114,111,102,105,108,101,32,116,121,112,101,32,120,109,112,0,10,120,
+109,112,10,32,32,32,32,50,53,53,53,10,51,99,51,102,55,56,55,48,54,49,54,51,54,
+98,54,53,55,52,50,48,54,50,54,53,54,55,54,57,54,101,51,100,50,50,101,102,98,98,
+98,102,50,50,50,48,54,57,54,52,51,100,50,50,53,55,51,53,52,100,51,48,52,100,55,
+48,52,51,54,53,54,56,54,57,10,52,56,55,97,55,50,54,53,53,51,55,97,52,101,53,52,
+54,51,55,97,54,98,54,51,51,57,54,52,50,50,51,102,51,101,48,97,51,99,55,56,51,
+97,55,56,54,100,55,48,54,100,54,53,55,52,54,49,50,48,55,56,54,100,54,99,54,101,
+55,51,51,97,55,56,10,51,100,50,50,54,49,54,52,54,102,54,50,54,53,51,97,54,101,
+55,51,51,97,54,100,54,53,55,52,54,49,50,102,50,50,50,48,55,56,51,97,55,56,54,
+100,55,48,55,52,54,98,51,100,50,50,53,56,52,100,53,48,50,48,52,51,54,102,55,50,
+54,53,50,48,10,51,52,50,101,51,52,50,101,51,48,50,100,52,53,55,56,54,57,55,54,
+51,50,50,50,51,101,48,97,50,48,51,99,55,50,54,52,54,54,51,97,53,50,52,52,52,54,
+50,48,55,56,54,100,54,99,54,101,55,51,51,97,55,50,54,52,54,54,51,100,50,50,54,
+56,10,55,52,55,52,55,48,51,97,50,102,50,102,55,55,55,55,55,55,50,101,55,55,51,
+51,50,101,54,102,55,50,54,55,50,102,51,49,51,57,51,57,51,57,50,102,51,48,51,50,
+50,102,51,50,51,50,50,100,55,50,54,52,54,54,50,100,55,51,55,57,54,101,55,52,10,
+54,49,55,56,50,100,54,101,55,51,50,51,50,50,51,101,48,97,50,48,50,48,51,99,55,
+50,54,52,54,54,51,97,52,52,54,53,55,51,54,51,55,50,54,57,55,48,55,52,54,57,54,
+102,54,101,50,48,55,50,54,52,54,54,51,97,54,49,54,50,54,102,55,53,10,55,52,51,
+100,50,50,50,50,48,97,50,48,50,48,50,48,50,48,55,56,54,100,54,99,54,101,55,51,
+51,97,54,53,55,56,54,57,54,54,51,100,50,50,54,56,55,52,55,52,55,48,51,97,50,
+102,50,102,54,101,55,51,50,101,54,49,54,52,54,102,54,50,54,53,10,50,101,54,51,
+54,102,54,100,50,102,54,53,55,56,54,57,54,54,50,102,51,49,50,101,51,48,50,102,
+50,50,48,97,50,48,50,48,50,48,50,48,55,56,54,100,54,99,54,101,55,51,51,97,55,
+52,54,57,54,54,54,54,51,100,50,50,54,56,55,52,55,52,55,48,10,51,97,50,102,50,
+102,54,101,55,51,50,101,54,49,54,52,54,102,54,50,54,53,50,101,54,51,54,102,54,
+100,50,102,55,52,54,57,54,54,54,54,50,102,51,49,50,101,51,48,50,102,50,50,48,97,
+50,48,50,48,50,48,54,53,55,56,54,57,54,54,51,97,53,48,10,54,57,55,56,54,53,54,
+99,53,56,52,52,54,57,54,100,54,53,54,101,55,51,54,57,54,102,54,101,51,100,50,
+50,51,56,51,50,50,50,48,97,50,48,50,48,50,48,54,53,55,56,54,57,54,54,51,97,53,
+48,54,57,55,56,54,53,54,99,53,57,52,52,54,57,10,54,100,54,53,54,101,55,51,54,
+57,54,102,54,101,51,100,50,50,51,49,51,50,51,56,50,50,48,97,50,48,50,48,50,48,
+55,52,54,57,54,54,54,54,51,97,53,50,54,53,55,51,54,102,54,99,55,53,55,52,54,57,
+54,102,54,101,53,53,54,101,54,57,55,52,10,51,100,50,50,51,50,50,50,48,97,50,48,
+50,48,50,48,55,52,54,57,54,54,54,54,51,97,53,57,53,50,54,53,55,51,54,102,54,99,
+55,53,55,52,54,57,54,102,54,101,51,100,50,50,51,49,51,52,51,52,50,48,50,102,50,
+48,51,49,50,50,48,97,50,48,10,50,48,50,48,55,52,54,57,54,54,54,54,51,97,53,56,
+53,50,54,53,55,51,54,102,54,99,55,53,55,52,54,57,54,102,54,101,51,100,50,50,51,
+49,51,52,51,52,50,48,50,102,50,48,51,49,50,50,50,102,51,101,48,97,50,48,51,99,
+50,102,55,50,54,52,10,54,54,51,97,53,50,52,52,52,54,51,101,48,97,51,99,50,102,
+55,56,51,97,55,56,54,100,55,48,54,100,54,53,55,52,54,49,51,101,48,97,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,48,97,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,48,97,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,48,97,50,48,10,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,48,97,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,48,97,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,48,97,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,48,
+97,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,48,97,10,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,48,97,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,48,97,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,48,97,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,48,97,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,10,48,97,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,48,97,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,48,
+97,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,48,97,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,48,97,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,48,97,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,48,97,50,48,50,48,50,48,50,48,50,48,10,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,48,97,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,
+48,50,48,50,48,50,48,50,48,10,50,48,50,48,50,48,50,48,50,48,50,48,50,48,50,48,
+50,48,50,48,50,48,50,48,50,48,50,48,50,48,48,97,51,99,51,102,55,56,55,48,54,49,
+54,51,54,98,54,53,55,52,50,48,54,53,54,101,54,52,51,100,50,50,55,55,50,50,51,
+102,51,101,10,87,123,188,247,0,0,9,241,73,68,65,84,88,71,109,87,105,144,85,197,
+21,254,186,239,242,222,155,25,102,88,12,14,46,227,16,96,12,26,80,118,103,16,
+113,3,5,89,203,10,70,75,42,106,170,48,196,16,141,154,20,18,177,8,41,21,149,82,
+81,244,71,48,166,42,75,37,96,22,29,5,9,155,131,37,139,16,65,113,153,25,71,8,66,
+153,165,148,137,226,204,91,238,210,55,223,233,251,30,49,58,77,53,115,223,237,
+190,167,207,249,206,57,223,57,173,218,59,223,128,163,92,104,147,32,138,12,84,
+162,225,58,62,100,36,137,66,38,147,65,177,88,4,31,225,186,46,130,56,134,210,9,
+188,140,139,158,82,30,78,198,65,20,26,238,5,60,237,91,57,242,157,231,184,8,75,1,
+148,82,118,130,223,12,168,27,152,62,127,97,104,3,23,9,52,226,242,76,228,173,50,
+118,81,169,4,249,124,15,5,198,86,160,85,138,135,185,78,22,189,61,37,104,30,104,
+98,5,87,103,184,158,227,51,191,113,249,206,24,132,97,152,202,41,79,101,13,74,
+240,229,225,26,83,131,68,203,193,49,12,2,24,45,31,184,246,35,199,113,64,120,104,
+177,139,222,82,137,104,228,16,169,88,187,137,250,238,137,79,62,251,246,238,93,
+187,250,83,232,137,113,227,199,71,77,77,77,71,78,22,78,222,149,209,94,41,227,
+249,68,165,68,153,148,65,52,42,255,250,26,174,67,200,211,161,211,153,104,139,
+136,60,151,104,133,235,106,68,38,132,118,29,132,145,25,250,139,103,158,217,186,
+105,227,214,97,199,143,253,131,240,41,56,70,67,211,13,67,134,12,198,236,249,215,
+220,178,112,225,245,187,170,171,252,233,132,58,53,216,162,233,244,121,184,12,
+213,217,222,97,31,100,183,5,138,10,40,229,88,248,5,21,223,23,69,138,242,46,179,
+252,222,159,183,183,190,176,121,104,130,44,178,153,254,152,56,102,10,98,198,196,
+161,183,246,163,55,255,31,120,185,24,87,207,188,20,15,220,191,242,128,49,193,
+196,40,14,98,71,149,229,81,137,218,218,218,20,213,47,12,87,39,97,89,1,5,35,112,
+241,3,109,53,151,169,24,3,69,56,158,118,215,172,121,114,127,235,11,155,134,122,
+110,45,150,46,125,16,45,205,151,211,184,156,85,160,95,181,135,109,59,94,194,170,
+71,238,69,235,11,127,197,160,1,3,198,222,241,163,239,63,79,9,179,147,10,242,
+125,123,128,56,19,70,9,26,9,52,135,24,136,66,137,138,184,196,103,122,194,247,
+125,245,234,206,221,109,191,122,246,119,163,20,170,112,255,202,53,184,184,249,
+106,6,99,21,181,118,224,185,89,20,243,6,151,77,189,6,203,151,61,4,159,10,62,251,
+203,223,98,223,190,191,141,75,143,48,167,142,234,35,6,233,70,30,46,43,137,157,
+113,249,131,116,138,117,68,166,186,189,189,115,50,19,18,115,103,45,192,248,177,
+23,35,10,178,60,184,14,90,101,9,105,22,97,192,248,40,41,76,110,158,134,185,179,
+175,227,59,31,7,14,188,233,126,249,176,190,178,160,18,129,68,168,156,50,246,111,
+100,115,93,16,160,207,146,55,15,190,131,160,148,96,204,133,205,40,246,42,248,78,
+53,24,151,20,232,160,144,15,80,83,221,143,252,193,12,9,52,206,251,198,88,196,
+92,123,243,224,161,56,149,92,65,160,239,161,157,47,40,165,202,81,43,239,44,26,
+212,56,8,130,248,224,129,3,240,189,44,134,15,111,66,198,175,161,229,220,39,123,
+153,1,53,53,57,20,11,198,198,144,239,229,48,98,68,19,60,47,131,183,223,126,183,
+88,62,162,143,99,255,55,180,48,147,107,35,228,203,27,211,223,76,195,184,177,
+177,129,86,149,112,244,232,17,166,98,17,145,216,38,228,198,45,226,127,215,35,
+123,122,224,90,47,142,29,63,76,18,42,161,190,190,254,36,18,221,135,220,175,156,
+162,203,169,167,210,116,41,127,36,40,72,124,184,218,137,167,78,157,130,108,149,
+135,182,157,91,200,7,12,80,29,17,58,11,144,245,171,226,239,48,250,156,73,219,
+131,215,118,109,227,122,140,25,51,102,100,42,178,83,37,250,118,133,85,47,34,158,
+9,179,65,38,148,87,230,1,199,42,101,146,200,204,152,57,237,125,147,228,177,
+243,181,205,120,175,99,31,81,233,229,222,34,21,76,200,142,204,29,174,105,175,
+136,119,59,247,98,123,91,171,85,104,250,244,43,125,77,6,53,166,98,28,229,39,95,
+85,66,71,41,251,83,63,42,65,14,168,40,18,89,10,117,108,38,12,31,209,120,83,115,
+203,120,148,130,147,184,231,222,219,177,105,243,6,120,126,36,52,129,124,177,100,
+41,124,71,219,75,88,198,181,56,233,193,228,201,147,208,216,216,56,75,228,168,
+50,11,138,187,84,31,222,176,172,35,100,33,22,11,92,177,74,103,197,119,36,33,81,
+111,207,83,79,175,217,187,224,186,121,40,20,63,197,99,143,63,136,205,91,90,89,
+17,149,240,4,182,110,219,132,135,30,89,137,124,161,27,243,230,207,196,186,103,
+158,218,67,22,125,79,170,171,84,80,97,191,40,138,208,91,232,65,108,34,235,182,
+34,43,101,41,40,165,65,104,161,150,169,211,103,85,174,15,162,152,148,226,32,40,
+18,137,112,206,178,101,75,183,141,190,224,124,107,49,139,55,74,20,98,40,208,
+247,61,6,102,128,81,163,206,199,138,21,247,173,47,20,10,45,130,105,38,227,217,
+170,88,98,33,75,203,112,130,79,79,118,227,147,238,19,164,238,188,157,172,39,14,
+9,141,126,42,79,139,136,69,37,101,66,177,192,243,60,233,11,62,102,74,62,76,82,
+162,50,9,38,76,152,96,149,148,67,46,188,112,12,171,90,6,29,29,93,193,231,159,23,
+158,20,223,107,126,28,70,37,155,214,242,189,252,22,20,4,101,73,83,249,93,118,
+129,197,223,22,159,116,166,164,45,127,197,255,217,108,214,30,24,4,17,118,239,
+126,61,137,194,4,35,207,29,133,65,3,79,39,180,202,90,87,83,93,135,97,67,207,101,
+63,224,153,3,111,28,202,184,174,239,136,229,41,145,41,203,41,34,75,179,204,139,
+65,50,108,191,192,227,221,83,197,226,212,72,35,213,214,114,250,174,187,187,155,
+188,190,79,255,229,207,47,206,223,183,247,157,135,227,64,161,101,210,101,164,94,
+32,173,90,160,146,53,152,48,126,10,142,28,237,204,254,224,182,59,159,187,100,
+202,164,127,206,155,63,235,195,150,150,139,158,173,170,170,122,217,36,113,94,24,
+95,14,15,67,246,29,236,92,114,185,156,85,66,181,119,118,88,6,252,127,69,82,37,
+94,106,221,56,106,245,234,71,175,232,62,209,51,203,113,170,91,76,224,231,38,76,
+184,20,75,190,119,23,206,58,123,56,203,116,10,181,75,234,62,246,81,39,158,88,
+187,10,239,180,239,71,18,247,218,56,169,98,149,252,241,79,238,196,220,185,179,
+47,247,60,231,21,81,34,117,133,177,127,5,25,213,222,222,14,169,136,142,231,218,
+128,50,73,32,10,12,88,187,246,233,59,215,173,251,245,45,42,169,61,99,120,227,88,
+76,155,190,0,83,155,175,68,255,65,131,105,56,59,7,82,95,28,146,176,24,55,137,
+229,112,33,167,8,255,254,248,24,118,182,109,196,43,109,47,163,189,243,32,15,138,
+177,232,214,155,112,251,29,183,77,85,137,121,53,45,72,58,45,76,68,80,189,253,
+214,33,194,209,207,194,33,41,215,211,243,233,232,229,203,151,255,126,203,150,29,
+231,185,172,120,75,22,255,20,211,167,221,72,70,172,163,94,14,164,159,8,36,152,0,
+219,204,74,200,136,44,9,48,41,227,174,71,106,87,228,6,213,139,23,95,124,14,79,
+174,125,136,27,3,92,50,181,217,172,121,124,245,24,173,205,33,203,158,182,81,165,
+225,75,126,184,132,86,211,227,180,202,209,222,153,119,223,125,207,235,219,183,
+239,110,168,171,61,3,43,239,123,156,254,190,10,85,85,167,161,80,136,88,130,93,
+27,88,68,144,169,71,146,226,193,177,73,27,78,66,12,135,235,113,28,165,5,149,
+194,217,39,226,155,163,70,99,207,174,93,248,224,112,151,58,124,164,107,241,244,
+171,166,29,103,237,56,40,116,45,25,161,125,95,160,15,108,239,199,96,187,97,103,
+219,158,129,190,219,31,171,87,173,195,216,11,46,99,233,29,192,146,27,157,138,
+222,82,41,141,232,56,182,201,99,93,32,214,136,95,77,148,240,119,134,41,153,35,
+186,213,136,131,12,198,140,190,24,143,174,94,135,154,220,215,176,99,251,107,120,
+125,239,254,7,136,182,170,196,154,14,216,239,101,115,210,5,71,151,175,88,249,
+179,165,33,133,44,188,97,49,154,190,62,142,66,171,73,48,20,200,86,91,14,9,73,54,
+174,207,190,136,133,73,44,141,227,52,88,45,205,10,141,11,125,115,198,180,44,138,
+121,71,64,127,148,242,62,70,142,156,136,57,115,174,167,66,46,86,63,242,196,32,
+130,214,84,9,119,45,36,81,40,244,158,182,97,195,134,223,124,208,245,193,192,179,
+207,26,134,111,93,187,144,13,8,157,29,123,105,59,109,42,221,140,177,129,26,210,
+223,18,197,158,167,109,129,137,152,86,202,94,92,202,118,73,185,230,118,135,37,
+211,247,170,17,20,20,22,222,120,11,59,231,6,116,117,29,118,159,127,190,117,69,
+84,142,35,29,209,145,142,155,61,255,15,235,255,116,70,93,221,233,184,249,59,
+139,104,5,153,138,157,175,133,88,167,80,11,2,162,172,237,106,89,5,227,40,96,239,
+79,74,54,129,205,0,197,12,136,19,42,39,237,16,247,243,106,192,192,78,121,223,
+146,26,207,91,116,235,98,42,31,99,195,31,215,79,114,41,75,134,155,48,178,185,
+195,59,114,248,56,130,162,143,230,139,166,216,194,164,43,209,29,167,85,76,243,
+191,48,76,155,28,199,241,108,76,164,205,108,74,90,70,114,154,123,36,150,4,21,
+113,179,40,171,29,9,204,34,41,187,26,227,199,93,100,255,190,223,113,204,72,44,
+249,76,101,22,35,15,135,187,62,26,98,34,31,67,234,207,177,27,148,244,134,210,
+116,136,134,101,4,36,215,229,224,180,175,55,246,112,197,158,80,131,190,86,25,72,
+95,85,25,210,97,185,90,89,235,131,82,104,175,114,48,164,97,93,139,51,235,155,
+104,168,151,251,232,248,103,20,202,119,212,86,31,61,122,108,149,4,80,67,67,131,
+189,136,228,195,30,114,127,129,26,74,235,205,128,67,234,83,200,83,249,222,152,
+118,58,94,249,89,242,46,172,108,42,95,195,180,101,87,47,35,233,202,106,232,196,
+168,98,176,15,30,124,26,254,254,161,170,233,234,234,194,208,198,122,81,52,202,
+53,156,51,196,44,186,245,230,127,13,169,111,200,38,186,23,253,6,120,82,231,221,
+176,196,226,159,208,145,112,107,172,97,9,97,81,9,159,217,14,33,166,242,18,73,
+230,4,103,29,223,243,217,94,114,184,238,68,118,63,97,36,82,174,152,47,212,204,
+238,14,243,174,189,2,19,155,135,117,203,225,246,210,218,222,241,22,3,134,23,84,
+238,147,74,103,27,19,11,113,26,120,114,249,176,150,90,139,203,237,112,5,133,83,
+163,124,159,80,105,166,84,154,25,123,221,51,105,57,150,247,65,216,203,236,81,
+116,89,108,93,41,107,255,5,119,155,194,247,64,241,254,70,0,0,0,0,73,69,78,68,
+174,66,96,130};
+static Fl_Image *image_fd_user() {
+ static Fl_Image *image = NULL;
+ if (!image)
+ image = new Fl_PNG_Image("fd_user.png", idata_fd_user, 8612);
+ return image;
}
Fl_Group *w_settings_i18n_tab=(Fl_Group *)0;
@@ -1011,6 +2091,9 @@ static void cb_i18n_pos_set_input(Fl_Int_Input* o, void* v) {
}
static void cb_Close(Fl_Button*, void*) {
+ if (g_shell_config)
+ g_shell_config->write(fluid_prefs, FD_STORE_USER);
+ g_layout_list.write(fluid_prefs, FD_STORE_USER);
settings_window->hide();
}
@@ -1527,50 +2610,153 @@ ped using octal notation `\\0123`. If this option is checked, Fluid will write\
w_settings_shell_tab->labelsize(11);
w_settings_shell_tab->callback((Fl_Callback*)cb_w_settings_shell_tab);
w_settings_shell_tab->hide();
- { Fl_Input* o = new Fl_Input(100, 78, 220, 20, "Command:");
- o->tooltip("external shell command");
- o->labelfont(1);
- o->labelsize(11);
- o->textfont(4);
- o->textsize(11);
- o->callback((Fl_Callback*)cb_Command);
- } // Fl_Input* o
- { Fl_Check_Button* o = new Fl_Check_Button(100, 98, 220, 20, "save .fl project file");
- o->tooltip("save the project to the .fl file before running the command");
- o->down_box(FL_DOWN_BOX);
- o->labelsize(11);
- o->callback((Fl_Callback*)cb_save);
- } // Fl_Check_Button* o
- { Fl_Check_Button* o = new Fl_Check_Button(100, 118, 220, 19, "save source code");
- o->tooltip("generate the source code and header file before running the command");
- o->down_box(FL_DOWN_BOX);
- o->labelsize(11);
- o->callback((Fl_Callback*)cb_save1);
- } // Fl_Check_Button* o
- { Fl_Check_Button* o = new Fl_Check_Button(100, 137, 220, 20, "save i18n strings");
- o->tooltip("save the internationalisation string before running the command");
- o->down_box(FL_DOWN_BOX);
- o->labelsize(11);
- o->callback((Fl_Callback*)cb_save2);
- } // Fl_Check_Button* o
- { shell_use_fl_button = new Fl_Check_Button(100, 194, 220, 19, "save settings in .fl project files");
- shell_use_fl_button->tooltip("check to read and write shell command from and to .fl files");
- shell_use_fl_button->down_box(FL_DOWN_BOX);
- shell_use_fl_button->labelsize(11);
- shell_use_fl_button->callback((Fl_Callback*)cb_shell_use_fl_button);
- shell_use_fl_button->deactivate();
- } // Fl_Check_Button* shell_use_fl_button
- { Fl_Button* o = new Fl_Button(100, 218, 115, 20, "save as default");
- o->tooltip("update the Fluid app settings for external shell commands to the current sett\
-ings");
- o->labelsize(11);
- o->callback((Fl_Callback*)cb_save3);
- } // Fl_Button* o
- { Fl_Return_Button* o = new Fl_Return_Button(100, 162, 100, 20, "Run");
- o->tooltip("save selected files and run the command");
- o->labelsize(11);
- o->callback((Fl_Callback*)cb_Run);
- } // Fl_Return_Button* o
+ { w_settings_shell_list = new Fl_Browser(100, 90, 220, 110, "Shell \ncommand \nlist:");
+ w_settings_shell_list->type(3);
+ w_settings_shell_list->labelfont(1);
+ w_settings_shell_list->labelsize(11);
+ w_settings_shell_list->textsize(13);
+ w_settings_shell_list->callback((Fl_Callback*)cb_w_settings_shell_list);
+ w_settings_shell_list->align(Fl_Align(FL_ALIGN_LEFT));
+ } // Fl_Browser* w_settings_shell_list
+ { w_settings_shell_toolbox = new Fl_Group(100, 200, 220, 22);
+ w_settings_shell_toolbox->callback((Fl_Callback*)cb_w_settings_shell_toolbox);
+ { Fl_Button* o = new Fl_Button(100, 200, 24, 22, "+");
+ o->labelsize(11);
+ o->callback((Fl_Callback*)cb_8);
+ } // Fl_Button* o
+ { w_settings_shell_dup = new Fl_Button(124, 200, 24, 22, "++");
+ w_settings_shell_dup->labelsize(11);
+ w_settings_shell_dup->callback((Fl_Callback*)cb_w_settings_shell_dup);
+ w_settings_shell_dup->deactivate();
+ } // Fl_Button* w_settings_shell_dup
+ { w_settings_shell_remove = new Fl_Button(148, 200, 24, 22, "-");
+ w_settings_shell_remove->labelsize(11);
+ w_settings_shell_remove->callback((Fl_Callback*)cb_w_settings_shell_remove);
+ w_settings_shell_remove->deactivate();
+ } // Fl_Button* w_settings_shell_remove
+ { w_settings_shell_menu = new Fl_Menu_Button(172, 200, 24, 22);
+ w_settings_shell_menu->labelsize(11);
+ w_settings_shell_menu->textsize(11);
+ w_settings_shell_menu->menu(menu_w_settings_shell_menu);
+ } // Fl_Menu_Button* w_settings_shell_menu
+ { w_settings_shell_play = new Fl_Button(270, 200, 50, 22, "Run");
+ w_settings_shell_play->labelsize(11);
+ w_settings_shell_play->callback((Fl_Callback*)cb_w_settings_shell_play);
+ w_settings_shell_play->deactivate();
+ } // Fl_Button* w_settings_shell_play
+ w_settings_shell_toolbox->end();
+ } // Fl_Group* w_settings_shell_toolbox
+ { w_settings_shell_cmd = new Fl_Group(10, 235, 320, 291);
+ w_settings_shell_cmd->callback((Fl_Callback*)cb_w_settings_shell_cmd);
+ { Fl_Input* o = new Fl_Input(100, 246, 220, 20, "Name:");
+ o->labelfont(1);
+ o->labelsize(11);
+ o->textfont(4);
+ o->textsize(11);
+ o->callback((Fl_Callback*)cb_Name);
+ o->when(FL_WHEN_RELEASE | FL_WHEN_CHANGED | FL_WHEN_ENTER_KEY);
+ } // Fl_Input* o
+ { Fl_Input* o = new Fl_Input(100, 272, 220, 20, "Label:");
+ o->labelfont(1);
+ o->labelsize(11);
+ o->textfont(4);
+ o->textsize(11);
+ o->callback((Fl_Callback*)cb_Label);
+ } // Fl_Input* o
+ { Fl_Shortcut_Button* o = new Fl_Shortcut_Button(100, 297, 130, 20, "Shortcut");
+ o->box(FL_UP_BOX);
+ o->color(FL_BACKGROUND_COLOR);
+ o->selection_color(FL_BACKGROUND_COLOR);
+ o->labeltype(FL_NORMAL_LABEL);
+ o->labelfont(0);
+ o->labelsize(11);
+ o->labelcolor(FL_FOREGROUND_COLOR);
+ o->callback((Fl_Callback*)cb_Shortcut);
+ o->align(Fl_Align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE));
+ o->when(FL_WHEN_RELEASE);
+ } // Fl_Shortcut_Button* o
+ { Fl_Choice* o = new Fl_Choice(100, 322, 130, 20, "Store:");
+ o->down_box(FL_BORDER_BOX);
+ o->labelfont(1);
+ o->labelsize(11);
+ o->textsize(11);
+ o->callback((Fl_Callback*)cb_Store);
+ o->menu(menu_Store);
+ } // Fl_Choice* o
+ { Fl_Choice* o = new Fl_Choice(100, 348, 130, 20, "Condition:");
+ o->down_box(FL_BORDER_BOX);
+ o->labelfont(1);
+ o->labelsize(11);
+ o->textsize(11);
+ o->callback((Fl_Callback*)cb_Condition);
+ o->menu(menu_Condition);
+ } // Fl_Choice* o
+ { Fl_Input* o = new Fl_Input(230, 348, 90, 20, "Label:");
+ o->labelfont(1);
+ o->labelsize(11);
+ o->textfont(4);
+ o->textsize(11);
+ o->callback((Fl_Callback*)cb_Label1);
+ o->hide();
+ } // Fl_Input* o
+ { Fl_Text_Editor* o = w_settings_shell_command = new Fl_Text_Editor(100, 373, 196, 80, "Shell script:");
+ w_settings_shell_command->labelfont(1);
+ w_settings_shell_command->labelsize(11);
+ w_settings_shell_command->textfont(4);
+ w_settings_shell_command->textsize(12);
+ w_settings_shell_command->callback((Fl_Callback*)cb_w_settings_shell_command);
+ w_settings_shell_command->align(Fl_Align(FL_ALIGN_LEFT));
+ o->buffer(new Fl_Text_Buffer);
+ } // Fl_Text_Editor* w_settings_shell_command
+ { Fl_Group* o = new Fl_Group(296, 373, 24, 44);
+ { w_settings_shell_text_macros = new Fl_Menu_Button(296, 373, 24, 22);
+ w_settings_shell_text_macros->labelsize(11);
+ w_settings_shell_text_macros->textsize(11);
+ w_settings_shell_text_macros->callback((Fl_Callback*)cb_w_settings_shell_text_macros);
+ w_settings_shell_text_macros->menu(menu_w_settings_shell_text_macros);
+ } // Fl_Menu_Button* w_settings_shell_text_macros
+ { Fl_Button* o = new Fl_Button(296, 395, 24, 22, "@square");
+ o->tooltip("open big code editor");
+ o->labelsize(11);
+ o->labelcolor(FL_BACKGROUND_COLOR);
+ o->callback((Fl_Callback*)cb_square);
+ } // Fl_Button* o
+ o->end();
+ } // Fl_Group* o
+ { Fl_Check_Button* o = new Fl_Check_Button(100, 458, 220, 20, "save .fl project file");
+ o->tooltip("save the project to the .fl file before running the command");
+ o->down_box(FL_DOWN_BOX);
+ o->labelsize(11);
+ o->callback((Fl_Callback*)cb_save);
+ } // Fl_Check_Button* o
+ { Fl_Check_Button* o = new Fl_Check_Button(100, 478, 220, 19, "save source code");
+ o->tooltip("generate the source code and header file before running the command");
+ o->down_box(FL_DOWN_BOX);
+ o->labelsize(11);
+ o->callback((Fl_Callback*)cb_save1);
+ } // Fl_Check_Button* o
+ { Fl_Check_Button* o = new Fl_Check_Button(100, 497, 220, 20, "save i18n strings");
+ o->tooltip("save the internationalisation strings before running the command");
+ o->down_box(FL_DOWN_BOX);
+ o->labelsize(11);
+ o->callback((Fl_Callback*)cb_save2);
+ } // Fl_Check_Button* o
+ w_settings_shell_cmd->end();
+ } // Fl_Group* w_settings_shell_cmd
+ { Fl_Box* o = w_settings_shell_fd_project = new Fl_Box(20, 70, 16, 15);
+ w_settings_shell_fd_project->bind_image( image_fd_project() );
+ w_settings_shell_fd_project->labelsize(11);
+ w_settings_shell_fd_project->hide();
+ w_settings_shell_fd_project->deactivate();
+ o->image()->scale(16, 16);
+ } // Fl_Box* w_settings_shell_fd_project
+ { Fl_Box* o = w_settings_shell_fd_user = new Fl_Box(20, 70, 16, 15);
+ w_settings_shell_fd_user->bind_image( image_fd_user() );
+ w_settings_shell_fd_user->labelsize(11);
+ w_settings_shell_fd_user->hide();
+ w_settings_shell_fd_user->deactivate();
+ o->image()->scale(16, 16);
+ } // Fl_Box* w_settings_shell_fd_user
o->image()->scale(36, 24);
w_settings_shell_tab->end();
} // Fl_Group* w_settings_shell_tab
@@ -1676,7 +2862,6 @@ le FLTK_GETTEXT_FOUND");
o->labelsize(11);
o->callback((Fl_Callback*)cb_Close);
} // Fl_Button* o
- settings_window->set_non_modal();
settings_window->end();
} // Fl_Double_Window* settings_window
w_settings_tabs->do_callback(w_settings_tabs, LOAD);
diff --git a/fluid/alignment_panel.fl b/fluid/alignment_panel.fl
index da80df3a4..ef9d48455 100644
--- a/fluid/alignment_panel.fl
+++ b/fluid/alignment_panel.fl
@@ -4,7 +4,7 @@ header_name {.h}
code_name {.cxx}
snap {
ver 1
- current_suite FLTK
+ current_suite {FLUID (based on FLTK)}
current_preset 0
suite {
name {FLUID (based on FLTK)}
@@ -91,6 +91,9 @@ decl {\#include <FL/fl_ask.H>} {private global
decl {\#include <string.h>} {private global
}
+decl {\#include "../src/flstring.h"} {private global
+}
+
decl {void init_scheme(void);} {
comment {// initialize the scheme from preferences} public global
}
@@ -104,11 +107,49 @@ decl {extern void i18n_cb(Fl_Choice *,void *);} {public local
decl {void scheme_cb(Fl_Scheme_Choice *, void *);} {public local
}
+decl {int w_settings_shell_list_selected;} {public local
+}
+
+Function {make_script_panel()} {open
+} {
+ Fl_Window script_panel {
+ label {Shell Script Editor}
+ callback {if (Fl::event()==FL_SHORTCUT && Fl::event_key()==FL_Escape)
+ return; // ignore Escape
+script_panel->hide(); // otherwise hide..} open
+ xywh {764 319 540 180} type Double labelsize 11 resizable
+ code0 {o->size_range(200, 150);} modal visible
+ } {
+ Fl_Text_Editor script_input {
+ xywh {10 10 520 130} box DOWN_BOX labelsize 11 when 13 textfont 4 textsize 11 resizable
+ code0 {script_input->buffer(new Fl_Text_Buffer);}
+ }
+ Fl_Group {} {open
+ xywh {10 150 520 20} labelsize 11
+ } {
+ Fl_Return_Button script_panel_ok {
+ label OK
+ xywh {400 150 60 20} labelsize 11 hotspot
+ }
+ Fl_Button script_panel_cancel {
+ label Cancel
+ xywh {470 150 60 20} labelsize 11
+ }
+ Fl_Box {} {
+ xywh {10 150 380 20} labelsize 11 resizable
+ }
+ }
+ }
+ code {// Enable line numbers
+script_input->linenumber_width(60);
+script_input->linenumber_size(script_input->Fl_Text_Display::textsize());} {}
+}
+
Function {make_settings_window()} {open
} {
Fl_Window settings_window {
label {FLUID Settings} open
- xywh {423 204 340 580} type Double align 80 non_modal visible
+ xywh {392 362 340 580} type Double align 80 visible
} {
Fl_Tabs w_settings_tabs {
callback {propagate_load(o, v);} open
@@ -758,73 +799,528 @@ g_layout_list.update_dialogs();}
}
Fl_Group w_settings_shell_tab {
label Shell
- callback {propagate_load(o, v);}
+ callback {propagate_load(o, v);} open
image {icons/shell_64.png} compress_image 1 xywh {10 60 320 480} labelsize 11 hide
code0 {o->image()->scale(36, 24);}
} {
- Fl_Input {} {
- label {Command:}
+ Fl_Browser w_settings_shell_list {
+ label {Shell
+command
+list:}
callback {if (v == LOAD) {
- o->value(g_shell_command.c_str());
+ // load from g_shell_config
+ if (g_shell_config) {
+ o->clear();
+ w_settings_shell_list_selected = 0;
+ for (int i=0; i<g_shell_config->list_size; i++) {
+ Fd_Shell_Command *cmd = g_shell_config->list[i];
+ o->add(cmd->name.c_str());
+ if (cmd->storage == FD_STORE_USER)
+ o->icon(i+1, w_settings_shell_fd_user->image());
+ else if (cmd->storage == FD_STORE_PROJECT)
+ o->icon(i+1, w_settings_shell_fd_project->image());
+ }
+ }
} else {
- g_shell_command = o->value();
+// int prev_selected = w_settings_shell_list_selected;
+ w_settings_shell_list_selected = 0;
+ int selected = w_settings_shell_list->value();
+ if (selected) {
+ if (w_settings_shell_list->selected(selected))
+ w_settings_shell_list_selected = selected;
+ }
+ w_settings_shell_cmd->do_callback(w_settings_shell_cmd, LOAD);
+ w_settings_shell_toolbox->do_callback(w_settings_shell_toolbox, LOAD);
}}
- tooltip {external shell command} xywh {100 78 220 20} labelfont 1 labelsize 11 textfont 4 textsize 11
+ xywh {100 90 220 110} type Multi labelfont 1 labelsize 11 align 4 textsize 13
}
- Fl_Check_Button {} {
- label {save .fl project file}
- callback {if (v == LOAD) {
- o->value(g_shell_save_fl);
+ Fl_Group w_settings_shell_toolbox {
+ callback {if (v==LOAD) {
+ propagate_load(o, v);
+}} open
+ xywh {100 200 220 22}
+ } {
+ Fl_Button {} {
+ label {+}
+ callback {if (v != LOAD) {
+ int selected = w_settings_shell_list_selected;
+ Fd_Shell_Command *cmd = new Fd_Shell_Command("new shell command");
+ g_shell_config->insert(selected, cmd);
+ w_settings_shell_list->insert(selected+1, cmd->name.c_str());
+ w_settings_shell_list->deselect();
+ w_settings_shell_list->value(selected+1);
+ if (cmd->storage == FD_STORE_USER)
+ w_settings_shell_list->icon(selected+1, w_settings_shell_fd_user->image());
+ else if (cmd->storage == FD_STORE_PROJECT)
+ w_settings_shell_list->icon(selected+1, w_settings_shell_fd_project->image());
+ w_settings_shell_list->do_callback();
+ w_settings_shell_cmd->do_callback(w_settings_shell_cmd, LOAD);
+ w_settings_shell_toolbox->do_callback(w_settings_shell_toolbox, LOAD);
+ g_shell_config->rebuild_shell_menu();
+}}
+ xywh {100 200 24 22} labelsize 11
+ }
+ Fl_Button w_settings_shell_dup {
+ label {++}
+ callback {int selected = w_settings_shell_list_selected;
+if (v==LOAD) {
+ if (selected) {
+ o->activate();
+ } else {
+ o->deactivate();
+ }
} else {
- g_shell_save_fl = o->value();
+ if (!selected) return;
+ Fd_Shell_Command *cmd = new Fd_Shell_Command(g_shell_config->list[selected-1]);
+ g_shell_config->insert(selected, cmd);
+ w_settings_shell_list->insert(selected+1, cmd->name.c_str());
+ w_settings_shell_list->deselect();
+ w_settings_shell_list->deselect();
+ w_settings_shell_list->value(selected+1);
+ if (cmd->storage == FD_STORE_USER)
+ w_settings_shell_list->icon(selected+1, w_settings_shell_fd_user->image());
+ else if (cmd->storage == FD_STORE_PROJECT)
+ w_settings_shell_list->icon(selected+1, w_settings_shell_fd_project->image());
+ w_settings_shell_list->do_callback();
+ w_settings_shell_cmd->do_callback(w_settings_shell_cmd, LOAD);
+ w_settings_shell_toolbox->do_callback(w_settings_shell_toolbox, LOAD);
+ g_shell_config->rebuild_shell_menu();
}}
- tooltip {save the project to the .fl file before running the command} xywh {100 98 220 20} down_box DOWN_BOX labelsize 11
- }
- Fl_Check_Button {} {
- label {save source code}
- callback {if (v == LOAD) {
- o->value(g_shell_save_code);
+ xywh {124 200 24 22} labelsize 11 deactivate
+ }
+ Fl_Button w_settings_shell_remove {
+ label {-}
+ callback {int selected = w_settings_shell_list_selected;
+if (v==LOAD) {
+ if (selected) {
+ o->activate();
+ } else {
+ o->deactivate();
+ }
} else {
- g_shell_save_code = o->value();
+ if (!selected) return;
+ g_shell_config->remove(selected-1);
+ w_settings_shell_list->remove(selected);
+ if (selected <= w_settings_shell_list->size())
+ w_settings_shell_list->value(selected);
+ else
+ w_settings_shell_list->value(0);
+ w_settings_shell_list->do_callback();
+ w_settings_shell_cmd->do_callback(w_settings_shell_cmd, LOAD);
+ w_settings_shell_toolbox->do_callback(w_settings_shell_toolbox, LOAD);
+ g_shell_config->rebuild_shell_menu();
}}
- tooltip {generate the source code and header file before running the command} xywh {100 118 220 19} down_box DOWN_BOX labelsize 11
- }
- Fl_Check_Button {} {
- label {save i18n strings}
- callback {if (v == LOAD) {
- o->value(g_shell_save_strings);
+ xywh {148 200 24 22} labelsize 11 deactivate
+ }
+ Fl_Menu_Button w_settings_shell_menu {open
+ xywh {172 200 24 22} labelsize 11 textsize 11
+ } {
+ MenuItem {} {
+ label {Import...}
+ callback {if (v != LOAD)
+ Fd_Shell_Command_List::import_from_file();}
+ xywh {90 90 100 20} labelsize 11
+ }
+ MenuItem {} {
+ label {Export selected...}
+ callback {if (v != LOAD)
+ Fd_Shell_Command_List::export_selected();}
+ xywh {10 10 100 20} labelsize 11 divider
+ }
+ MenuItem {} {
+ label {Import Example Scripts:}
+ xywh {20 20 100 20} labelfont 1 labelsize 10 deactivate
+ }
+ MenuItem {} {
+ label {Compile with fltk-config}
+ xywh {30 30 100 20} labelsize 11
+ }
+ MenuItem {} {
+ label {Build and run}
+ xywh {40 40 100 20} labelsize 11
+ }
+ MenuItem {} {
+ label {Build with Xcode on macOS}
+ xywh {50 50 100 20} labelsize 11
+ }
+ MenuItem {} {
+ label {Build with CMake}
+ xywh {60 60 100 20} labelsize 11
+ }
+ }
+ Fl_Button w_settings_shell_play {
+ label Run
+ callback {int selected = w_settings_shell_list_selected;
+if (v==LOAD) {
+ if (selected) {
+ o->activate();
+ } else {
+ o->deactivate();
+ }
} else {
- g_shell_save_strings = o->value();
+ if (!selected) return;
+ Fd_Shell_Command *cmd = g_shell_config->list[selected-1];
+ cmd->run();
}}
- tooltip {save the internationalisation string before running the command} xywh {100 137 220 20} down_box DOWN_BOX labelsize 11
+ xywh {270 200 50 22} labelsize 11 deactivate
+ }
}
- Fl_Check_Button shell_use_fl_button {
- label {save settings in .fl project files}
- callback {if (v == LOAD) {
- o->value(g_shell_use_fl_settings);
+ Fl_Group w_settings_shell_cmd {
+ callback {if (v==LOAD) {
+ int selected = w_settings_shell_list_selected;
+ if (selected) {
+ o->activate();
+ } else {
+ o->deactivate();
+ }
+ propagate_load(o, v);
+}} open
+ xywh {10 235 320 291}
+ } {
+ Fl_Input {} {
+ label {Name:}
+ callback {int selected = w_settings_shell_list_selected;
+if (v == LOAD) {
+ if (selected) {
+ o->value(g_shell_config->list[selected-1]->name.c_str());
+ } else {
+ o->value("");
+ }
} else {
- g_shell_use_fl_settings = o->value();
- fluid_prefs.set("shell_use_fl", g_shell_use_fl_settings);
- if (g_shell_use_fl_settings) {
- shell_settings_read();
+ if (selected) {
+ Fd_Shell_Command *cmd = g_shell_config->list[selected-1];
+ cmd->name = o->value();
+ w_settings_shell_list->text(selected, o->value());
+ if (cmd->storage == FD_STORE_PROJECT) set_modflag(1);
+ }
+}}
+ xywh {100 246 220 20} labelfont 1 labelsize 11 when 13 textfont 4 textsize 11
+ }
+ Fl_Input {} {
+ label {Label:}
+ callback {int selected = w_settings_shell_list_selected;
+if (v == LOAD) {
+ if (selected) {
+ o->value(g_shell_config->list[selected-1]->label.c_str());
} else {
- shell_prefs_get();
+ o->value("");
+ }
+} else {
+ if (selected) {
+ Fd_Shell_Command *cmd = g_shell_config->list[selected-1];
+ cmd->label = o->value();
+ cmd->update_shell_menu();
+ if (cmd->storage == FD_STORE_PROJECT) set_modflag(1);
}
- w_settings_shell_tab->do_callback(w_settings_shell_tab, LOAD);
}}
- tooltip {check to read and write shell command from and to .fl files} xywh {100 194 220 19} down_box DOWN_BOX labelsize 11 deactivate
+ xywh {100 272 220 20} labelfont 1 labelsize 11 textfont 4 textsize 11
+ }
+ Fl_Button {} {
+ label Shortcut
+ callback {int selected = w_settings_shell_list_selected;
+if (v == LOAD) {
+ if (selected) {
+ o->value(g_shell_config->list[selected-1]->shortcut);
+ o->default_value(o->value());
+ } else {
+ o->value(0);
+ }
+} else {
+ if (selected) {
+ Fd_Shell_Command *cmd = g_shell_config->list[selected-1];
+ cmd->shortcut = o->value();
+ cmd->update_shell_menu();
+ if (cmd->storage == FD_STORE_PROJECT) set_modflag(1);
+ }
+}}
+ xywh {100 297 130 20} labelsize 11 align 16
+ code0 {\#include <FL/Fl_Shortcut_Button.H>}
+ class Fl_Shortcut_Button
+ }
+ Fl_Choice {} {
+ label {Store:}
+ callback {int selected = w_settings_shell_list_selected;
+if (v == LOAD) {
+ if (selected) {
+ Fd_Tool_Store ts = g_shell_config->list[selected-1]->storage;
+ o->value(o->find_item_with_argument((long)ts));
+ } else {
+ o->value(o->find_item_with_argument((long)FD_STORE_USER));
+ }
+} else {
+ if (selected) {
+ Fd_Shell_Command *cmd = g_shell_config->list[selected-1];
+ Fd_Tool_Store ts = (Fd_Tool_Store)(o->mvalue()->argument());
+ if (cmd->storage == FD_STORE_PROJECT) set_modflag(1);
+ cmd->storage = ts;
+ //w_settings_shell_list->text(selected, cmd->name.c_str());
+ if (cmd->storage == FD_STORE_USER)
+ w_settings_shell_list->icon(selected, w_settings_shell_fd_user->image());
+ else if (cmd->storage == FD_STORE_PROJECT)
+ w_settings_shell_list->icon(selected, w_settings_shell_fd_project->image());
+ if (cmd->storage == FD_STORE_PROJECT) set_modflag(1);
+ }
+}} open
+ xywh {100 322 130 20} down_box BORDER_BOX labelfont 1 labelsize 11 textsize 11
+ } {
+ MenuItem {} {
+ label {@fd_user User Setting}
+ user_data FD_STORE_USER user_data_type long
+ xywh {0 0 100 20} labelsize 11
+ }
+ MenuItem {} {
+ label {@fd_project Project File}
+ user_data FD_STORE_PROJECT user_data_type long
+ xywh {0 0 100 20} labelsize 11
+ }
+ }
+ Fl_Choice {} {
+ label {Condition:}
+ callback {int selected = w_settings_shell_list_selected;
+if (v == LOAD) {
+ if (selected) {
+ int cond = g_shell_config->list[selected-1]->condition;
+ o->value(o->find_item_with_argument(cond));
+ } else {
+ o->value(o->find_item_with_argument(0));
+ }
+} else {
+ if (selected) {
+ Fd_Shell_Command *cmd = g_shell_config->list[selected-1];
+ int cond = (int)(o->mvalue()->argument());
+ cmd->condition = cond;
+ g_shell_config->rebuild_shell_menu();
+ if (cmd->storage == FD_STORE_PROJECT) set_modflag(1);
+ }
+}} open
+ xywh {100 348 130 20} down_box BORDER_BOX labelfont 1 labelsize 11 textsize 11
+ } {
+ MenuItem {} {
+ label {all platforms}
+ user_data {Fd_Shell_Command::ALWAYS} user_data_type long
+ xywh {0 0 100 20} labelsize 11
+ }
+ MenuItem {} {
+ label {MS Windows only}
+ user_data {Fd_Shell_Command::WIN_ONLY} user_data_type long
+ xywh {0 0 100 20} labelsize 11
+ }
+ MenuItem {} {
+ label {Linux only}
+ user_data {Fd_Shell_Command::UX_ONLY} user_data_type long
+ xywh {0 0 100 20} labelsize 11
+ }
+ MenuItem {} {
+ label {macOS only}
+ user_data {Fd_Shell_Command::MAC_ONLY} user_data_type long
+ xywh {0 0 100 20} labelsize 11
+ }
+ MenuItem {} {
+ label {Linux and macOS}
+ user_data {Fd_Shell_Command::MAC_AND_UX_ONLY} user_data_type long
+ xywh {0 0 100 20} labelsize 11
+ }
+ MenuItem {} {
+ label {don't use}
+ user_data {Fd_Shell_Command::NEVER} user_data_type long
+ xywh {0 0 100 20} labelsize 11
+ }
+ }
+ Fl_Input {} {
+ label {Label:}
+ callback {if (v == LOAD) {
+// o->value(g_shell_command.c_str());
+} else {
+// g_shell_command = o->value();
+}}
+ xywh {230 348 90 20} labelfont 1 labelsize 11 textfont 4 textsize 11 hide
+ }
+ Fl_Text_Editor w_settings_shell_command {
+ label {Shell script:}
+ callback {int selected = w_settings_shell_list_selected;
+if (v == LOAD) {
+ if (selected) {
+ o->buffer()->text(g_shell_config->list[selected-1]->command.c_str());
+ } else {
+ o->buffer()->text("");
+ }
+} else {
+ if (selected) {
+ Fd_Shell_Command *cmd = g_shell_config->list[selected-1];
+ cmd->command = o->buffer()->text();
+ if (cmd->storage == FD_STORE_PROJECT) set_modflag(1);
+ }
+}}
+ xywh {100 373 196 80} labelfont 1 labelsize 11 align 4 textfont 4 textsize 12
+ code0 {o->buffer(new Fl_Text_Buffer);}
+ }
+ Fl_Group {} {open
+ xywh {296 373 24 44}
+ } {
+ Fl_Menu_Button w_settings_shell_text_macros {
+ callback {const Fl_Menu_Item *mi = o->mvalue();
+if (mi) {
+ char buffer[256];
+ fl_strlcpy(buffer, mi->label(), 255);
+ int n = (int)strlen(buffer)-1;
+ if (buffer[n]=='@') buffer[n] = 0;
+ char *word = buffer;
+ if (word[0]=='@') word++;
+ if (w_settings_shell_command->buffer()->selected()) {
+ int start = 0, end = 0;
+ w_settings_shell_command->buffer()->selection_position(&start, &end);
+ w_settings_shell_command->buffer()->replace(start, end, word);
+ } else {
+ int pos = w_settings_shell_command->insert_position();
+ w_settings_shell_command->buffer()->insert(pos, word);
+ }
+ w_settings_shell_command->do_callback(w_settings_shell_command, (void*)NULL);
+}} open
+ xywh {296 373 24 22} labelsize 11 textsize 11
+ } {
+ MenuItem {} {
+ label {@@BASENAME@@}
+ xywh {80 80 100 20} labelfont 4 labelsize 11
+ }
+ MenuItem {} {
+ label {@@PROJECTFILE_PATH@@}
+ xywh {0 0 100 20} labelfont 4 labelsize 11
+ }
+ MenuItem {} {
+ label {@@PROJECTFILE_NAME@@}
+ xywh {10 10 100 20} labelfont 4 labelsize 11
+ }
+ MenuItem {} {
+ label {@@CODEFILE_PATH@@}
+ xywh {20 20 100 20} labelfont 4 labelsize 11
+ }
+ MenuItem {} {
+ label {@@CODEFILE_NAME@@}
+ xywh {30 30 100 20} labelfont 4 labelsize 11
+ }
+ MenuItem {} {
+ label {@@HEADERFILE_PATH@@}
+ xywh {40 40 100 20} labelfont 4 labelsize 11
+ }
+ MenuItem {} {
+ label {@@HEADERFILE_NAME@@}
+ xywh {50 50 100 20} labelfont 4 labelsize 11
+ }
+ MenuItem {} {
+ label {@@TEXTFILE_PATH@@}
+ xywh {60 60 100 20} labelfont 4 labelsize 11
+ }
+ MenuItem {} {
+ label {@@TEXTFILE_NAME@@}
+ xywh {70 70 100 20} labelfont 4 labelsize 11
+ }
+ MenuItem {} {
+ label {@@FLTK_CONFIG@@}
+ comment {Not yet implemented}
+ xywh {70 70 100 20} labelfont 4 labelsize 11 hide
+ }
+ MenuItem {} {
+ label {@@TMPDIR@@}
+ xywh {70 70 100 20} labelfont 4 labelsize 11
+ }
+ }
+ Fl_Button {} {
+ label {@square}
+ callback {if (!script_panel) make_script_panel();
+script_input->buffer()->text(w_settings_shell_command->buffer()->text());
+script_panel->show();
+
+for (;;) {
+ Fl_Widget* w = Fl::readqueue();
+ if (w == script_panel_cancel) goto BREAK2;
+ else if (w == script_panel_ok) break;
+ else if (!w) Fl::wait();
+}
+
+w_settings_shell_command->buffer()->text(script_input->buffer()->text());
+w_settings_shell_command->do_callback();
+BREAK2:
+script_panel->hide();}
+ tooltip {open big code editor} xywh {296 395 24 22} labelsize 11 labelcolor 49
+ }
+ }
+ Fl_Check_Button {} {
+ label {save .fl project file}
+ callback {int selected = w_settings_shell_list_selected;
+if (v == LOAD) {
+ if (selected) {
+ o->value(g_shell_config->list[selected-1]->flags & Fd_Shell_Command::SAVE_PROJECT);
+ } else {
+ o->value(0);
+ }
+} else {
+ if (selected) {
+ Fd_Shell_Command *cmd = g_shell_config->list[selected-1];
+ int v = o->value();
+ if (v) {
+ cmd->flags |= Fd_Shell_Command::SAVE_PROJECT;
+ } else {
+ cmd->flags &= ~Fd_Shell_Command::SAVE_PROJECT;
+ }
+ if (cmd->storage == FD_STORE_PROJECT) set_modflag(1);
+ }
+}}
+ tooltip {save the project to the .fl file before running the command} xywh {100 458 220 20} down_box DOWN_BOX labelsize 11
+ }
+ Fl_Check_Button {} {
+ label {save source code}
+ callback {int selected = w_settings_shell_list_selected;
+if (v == LOAD) {
+ if (selected) {
+ o->value(g_shell_config->list[selected-1]->flags & Fd_Shell_Command::SAVE_SOURCECODE);
+ } else {
+ o->value(0);
+ }
+} else {
+ if (selected) {
+ Fd_Shell_Command *cmd = g_shell_config->list[selected-1];
+ int v = o->value();
+ if (v) {
+ cmd->flags |= Fd_Shell_Command::SAVE_SOURCECODE;
+ } else {
+ cmd->flags &= ~Fd_Shell_Command::SAVE_SOURCECODE;
+ }
+ if (cmd->storage == FD_STORE_PROJECT) set_modflag(1);
+ }
+}}
+ tooltip {generate the source code and header file before running the command} xywh {100 478 220 19} down_box DOWN_BOX labelsize 11
+ }
+ Fl_Check_Button {} {
+ label {save i18n strings}
+ callback {int selected = w_settings_shell_list_selected;
+if (v == LOAD) {
+ if (selected) {
+ o->value(g_shell_config->list[selected-1]->flags & Fd_Shell_Command::SAVE_STRINGS);
+ } else {
+ o->value(0);
+ }
+} else {
+ if (selected) {
+ Fd_Shell_Command *cmd = g_shell_config->list[selected-1];
+ int v = o->value();
+ if (v) {
+ cmd->flags |= Fd_Shell_Command::SAVE_STRINGS;
+ } else {
+ cmd->flags &= ~Fd_Shell_Command::SAVE_STRINGS;
+ }
+ if (cmd->storage == FD_STORE_PROJECT) set_modflag(1);
+ }
+}}
+ tooltip {save the internationalisation strings before running the command} xywh {100 497 220 20} down_box DOWN_BOX labelsize 11
+ }
}
- Fl_Button {} {
- label {save as default}
- callback {if (v != LOAD)
- shell_prefs_set();}
- tooltip {update the Fluid app settings for external shell commands to the current settings} xywh {100 218 115 20} labelsize 11
+ Fl_Box w_settings_shell_fd_project {
+ image {pixmaps/fd_project.png} compress_image 1 bind_image 1 bind_deimage 1 xywh {20 70 16 15} labelsize 11 hide deactivate
+ code0 {o->image()->scale(16, 16);}
}
- Fl_Return_Button {} {
- label Run
- callback {if (v != LOAD)
- do_shell_command(NULL, NULL);}
- tooltip {save selected files and run the command} xywh {100 162 100 20} labelsize 11
+ Fl_Box w_settings_shell_fd_user {
+ image {pixmaps/fd_user.png} compress_image 1 bind_image 1 bind_deimage 1 xywh {20 70 16 15} labelsize 11 hide deactivate
+ code0 {o->image()->scale(16, 16);}
}
}
Fl_Group w_settings_i18n_tab {
@@ -953,7 +1449,10 @@ g_layout_list.update_dialogs();}
}
Fl_Button {} {
label Close
- callback {settings_window->hide();}
+ callback {if (g_shell_config)
+ g_shell_config->write(fluid_prefs, FD_STORE_USER);
+g_layout_list.write(fluid_prefs, FD_STORE_USER);
+settings_window->hide();}
tooltip {Close this dialog.} xywh {230 550 100 20} labelsize 11
}
}
diff --git a/fluid/alignment_panel.h b/fluid/alignment_panel.h
index a084917b3..932398ee5 100644
--- a/fluid/alignment_panel.h
+++ b/fluid/alignment_panel.h
@@ -35,14 +35,23 @@ void init_scheme(void);
extern struct Fl_Menu_Item *dbmanager_item;
extern void i18n_cb(Fl_Choice *,void *);
extern void scheme_cb(Fl_Scheme_Choice *, void *);
+extern int w_settings_shell_list_selected;
#include <FL/Fl_Double_Window.H>
+extern Fl_Double_Window *script_panel;
+#include <FL/Fl_Text_Editor.H>
+extern Fl_Text_Editor *script_input;
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Return_Button.H>
+extern Fl_Return_Button *script_panel_ok;
+#include <FL/Fl_Button.H>
+extern Fl_Button *script_panel_cancel;
+#include <FL/Fl_Box.H>
+Fl_Double_Window* make_script_panel();
extern Fl_Double_Window *settings_window;
#include <FL/Fl_Tabs.H>
extern Fl_Tabs *w_settings_tabs;
-#include <FL/Fl_Group.H>
extern void scheme_cb(Fl_Scheme_Choice*, void*);
extern Fl_Scheme_Choice *scheme_choice;
-#include <FL/Fl_Box.H>
#include <FL/Fl_Check_Button.H>
extern Fl_Check_Button *tooltips_button;
extern Fl_Check_Button *completion_button;
@@ -68,7 +77,6 @@ extern Fl_Check_Button *avoid_early_includes_button;
extern Fl_Group *w_settings_layout_tab;
#include <FL/Fl_Choice.H>
extern Fl_Choice *layout_choice;
-#include <FL/Fl_Button.H>
#include <FL/Fl_Menu_Button.H>
extern Fl_Menu_Button *w_layout_menu;
#include <FL/Fl_Native_File_Chooser.H>
@@ -78,8 +86,19 @@ extern Fl_Button *preset_choice[3];
#include <FL/Fl_Value_Input.H>
extern Fl_Menu_Item fontmenu_w_default[];
extern Fl_Group *w_settings_shell_tab;
-extern Fl_Check_Button *shell_use_fl_button;
-#include <FL/Fl_Return_Button.H>
+#include <FL/Fl_Browser.H>
+extern Fl_Browser *w_settings_shell_list;
+extern Fl_Group *w_settings_shell_toolbox;
+extern Fl_Button *w_settings_shell_dup;
+extern Fl_Button *w_settings_shell_remove;
+extern Fl_Menu_Button *w_settings_shell_menu;
+extern Fl_Button *w_settings_shell_play;
+extern Fl_Group *w_settings_shell_cmd;
+#include <FL/Fl_Shortcut_Button.H>
+extern Fl_Text_Editor *w_settings_shell_command;
+extern Fl_Menu_Button *w_settings_shell_text_macros;
+extern Fl_Box *w_settings_shell_fd_project;
+extern Fl_Box *w_settings_shell_fd_user;
extern Fl_Group *w_settings_i18n_tab;
extern void i18n_type_cb(Fl_Choice*, void*);
extern Fl_Choice *i18n_type_chooser;
@@ -102,6 +121,10 @@ extern Fl_Menu_Item *w_layout_menu_storage[4];
#define w_layout_menu_load (menu_w_layout_menu+5)
#define w_layout_menu_save (menu_w_layout_menu+6)
#define w_layout_menu_delete (menu_w_layout_menu+7)
+extern Fl_Menu_Item menu_w_settings_shell_menu[];
+extern Fl_Menu_Item menu_Store[];
+extern Fl_Menu_Item menu_Condition[];
+extern Fl_Menu_Item menu_w_settings_shell_text_macros[];
extern Fl_Menu_Item menu_i18n_type_chooser[];
extern Fl_Double_Window *shell_run_window;
#include <FL/Fl_Simple_Terminal.H>
diff --git a/fluid/file.cxx b/fluid/file.cxx
index 163b41dee..d93a71a1a 100644
--- a/fluid/file.cxx
+++ b/fluid/file.cxx
@@ -137,7 +137,7 @@ int Fd_Project_Reader::open_read(const char *s) {
fin = stdin;
fname = "stdin";
} else {
- FILE *f = fl_fopen(s,"r");
+ FILE *f = fl_fopen(s, "r");
if (!f)
return 0;
fin = f;
@@ -325,29 +325,12 @@ void Fd_Project_Reader::read_children(Fl_Type *p, int paste, Strategy strategy,
goto CONTINUE;
}
- if (strcmp(c, "win_shell_cmd")==0) {
- if (shell_settings_windows.command)
- free((void*)shell_settings_windows.command);
- shell_settings_windows.command = fl_strdup(read_word());
- goto CONTINUE;
- } else if (strcmp(c, "win_shell_flags")==0) {
- shell_settings_windows.flags = atoi(read_word());
- goto CONTINUE;
- } else if (strcmp(c, "linux_shell_cmd")==0) {
- if (shell_settings_linux.command)
- free((void*)shell_settings_linux.command);
- shell_settings_linux.command = fl_strdup(read_word());
- goto CONTINUE;
- } else if (strcmp(c, "linux_shell_flags")==0) {
- shell_settings_linux.flags = atoi(read_word());
- goto CONTINUE;
- } else if (strcmp(c, "mac_shell_cmd")==0) {
- if (shell_settings_macos.command)
- free((void*)shell_settings_macos.command);
- shell_settings_macos.command = fl_strdup(read_word());
- goto CONTINUE;
- } else if (strcmp(c, "mac_shell_flags")==0) {
- shell_settings_macos.flags = atoi(read_word());
+ if (strcmp(c, "shell_commands")==0) {
+ if (g_shell_config) {
+ g_shell_config->read(this);
+ } else {
+ read_word();
+ }
goto CONTINUE;
}
}
@@ -431,7 +414,10 @@ int Fd_Project_Reader::read_project(const char *filename, int merge, Strategy st
}
}
selection_changed(Fl_Type::current);
- shell_settings_read();
+ if (g_shell_config) {
+ g_shell_config->rebuild_shell_menu();
+ g_shell_config->update_settings_dialog();
+ }
int ret = close_read();
undo_resume();
return ret;
@@ -816,23 +802,8 @@ int Fd_Project_Writer::write_project(const char *filename, int selected_only) {
write_string("\nheader_name"); write_word(g_project.header_file_name.c_str());
write_string("\ncode_name"); write_word(g_project.code_file_name.c_str());
g_layout_list.write(this);
-#if 0
- // https://github.com/fltk/fltk/issues/328
- // Project wide settings require a redesign.
- shell_settings_write();
- if (shell_settings_windows.command) {
- write_string("\nwin_shell_cmd"); write_word(shell_settings_windows.command);
- write_string("\nwin_shell_flags"); write_string("%d", shell_settings_windows.flags);
- }
- if (shell_settings_linux.command) {
- write_string("\nlinux_shell_cmd"); write_word(shell_settings_linux.command);
- write_string("\nlinux_shell_flags"); write_string("%d", shell_settings_linux.flags);
- }
- if (shell_settings_macos.command) {
- write_string("\nmac_shell_cmd"); write_word(shell_settings_macos.command);
- write_string("\nmac_shell_flags"); write_string("%d", shell_settings_macos.flags);
- }
-#endif
+ if (g_shell_config)
+ g_shell_config->write(this);
}
for (Fl_Type *p = Fl_Type::first; p;) {
diff --git a/fluid/fluid.cxx b/fluid/fluid.cxx
index 9533ecc5d..545a691ec 100644
--- a/fluid/fluid.cxx
+++ b/fluid/fluid.cxx
@@ -172,6 +172,9 @@ Fl_String g_code_filename_arg;
Fl_String g_header_filename_arg;
Fl_String g_launch_path;
+Fl_String tmpdir_path;
+bool tmpdir_create_called = false;
+
/** \var int Fluid_Project::header_file_set
If set, command line overrides header file name in .fl file.
*/
@@ -311,10 +314,6 @@ void Fluid_Project::reset() {
code_file_set = 0;
header_file_name = ".h";
code_file_name = ".cxx";
-
- g_layout_list.remove_all(FD_STORE_PROJECT);
- g_layout_list.current_suite(0);
- g_layout_list.current_preset(0);
}
void Fluid_Project::update_settings_dialog() {
@@ -324,6 +323,113 @@ void Fluid_Project::update_settings_dialog() {
}
}
+// make sure that a path name ends with a forward slash
+static Fl_String end_with_slash(const Fl_String &str) {
+ char last = str[str.size()-1];
+ if (last !='/' && last != '\\')
+ return str + "/";
+ else
+ return str;
+}
+
+/** Generate a path to a directory for temporary data storage.
+ The path is stored in g_tmpdir.
+ */
+static void create_tmpdir() {
+ if (tmpdir_create_called)
+ return;
+ tmpdir_create_called = true;
+
+ char buf[128];
+#if _WIN32
+ // The usual temp file locations on Windows are
+ // %system%\Windows\Temp
+ // %userprofiles%\AppData\Local
+ // usually resolving into
+ // C:/Windows/Temp/
+ // C:\Users\<username>\AppData\Local\Temp
+ fl_snprintf(buf, sizeof(buf)-1, "fluid-%d/", (long)GetCurrentProcessId());
+ Fl_String name = buf;
+ wchar_t tempdirW[FL_PATH_MAX+1];
+ char tempdir[FL_PATH_MAX+1];
+ unsigned len = GetTempPathW(FL_PATH_MAX, tempdirW);
+ if (len == 0) {
+ strcpy(tempdir, "c:/windows/temp/");
+ } else {
+ unsigned wn = fl_utf8fromwc(tempdir, FL_PATH_MAX, tempdirW, len);
+ tempdir[wn] = 0;
+ }
+ Fl_String path = tempdir;
+ end_with_slash(path);
+ path += name;
+ fl_make_path(path.c_str());
+ if (fl_access(path.c_str(), 6) == 0) tmpdir_path = path;
+#else
+ fl_snprintf(buf, sizeof(buf)-1, "fluid-%d/", getpid());
+ Fl_String name = buf;
+ Fl_String path = fl_getenv("TMPDIR");
+ if (!path.empty()) {
+ end_with_slash(path);
+ path += name;
+ fl_make_path(path.c_str());
+ if (fl_access(path.c_str(), 6) == 0) tmpdir_path = path;
+ }
+ if (tmpdir_path.empty()) {
+ path = Fl_String("/tmp/") + name;
+ fl_make_path(path.c_str());
+ if (fl_access(path.c_str(), 6) == 0) tmpdir_path = path;
+ }
+#endif
+ if (tmpdir_path.empty()) {
+ char pbuf[FL_PATH_MAX+1];
+ fluid_prefs.get_userdata_path(pbuf, FL_PATH_MAX);
+ path = Fl_String(pbuf);
+ end_with_slash(path);
+ path += name;
+ fl_make_path(path.c_str());
+ if (fl_access(path.c_str(), 6) == 0) tmpdir_path = path;
+ }
+ if (tmpdir_path.empty())
+ fl_alert("Can't create directory for temporary data storage.");
+}
+
+/** Delete the temporary directory that was created in set_tmpdir. */
+static void delete_tmpdir() {
+ // was a temporary directory created
+ if (!tmpdir_create_called)
+ return;
+ if (tmpdir_path.empty())
+ return;
+
+ // first delete all files that may still be left in the temp directory
+ struct dirent **de;
+ int n_de = fl_filename_list(tmpdir_path.c_str(), &de);
+ if (n_de >= 0) {
+ for (int i=0; i<n_de; i++) {
+ Fl_String path = tmpdir_path + de[i]->d_name;
+ fl_unlink(path.c_str());
+ }
+ fl_filename_free_list(&de, n_de);
+ }
+
+ // then delete the directory itself
+ if (fl_rmdir(tmpdir_path.c_str()) < 0) {
+ fl_alert("WARNING: Can't delete tmpdir '%s': %s", tmpdir_path.c_str(), strerror(errno));
+ }
+}
+
+/**
+ Return the path to a temporary directory for this instance of FLUID.
+ Fluid will do its best to clear and delete this directory when exiting.
+ \return the path to the temporary directory, ending in a '/', or and empty
+ string is no directory could be created.
+ */
+const Fl_String &get_tmpdir() {
+ if (!tmpdir_create_called)
+ create_tmpdir();
+ return tmpdir_path;
+}
+
/**
Give the user the opportunity to save a project before clearing it.
@@ -397,7 +503,7 @@ void enter_project_dir() {
// store the current working directory for later
app_work_dir = fl_getcwd();
// set the current directory to the path of our .fl file
- Fl_String project_path = fl_filename_path(fl_filename_absolute(Fl_String(filename)));
+ Fl_String project_path = fl_filename_path(fl_filename_absolute(filename));
if (fl_chdir(project_path.c_str()) == -1) {
fprintf(stderr, "** Fluid internal error: enter_project_dir() can't chdir to %s: %s\n",
project_path.c_str(), strerror(errno));
@@ -733,6 +839,8 @@ void exit_cb(Fl_Widget *,void *) {
if (help_dialog)
delete help_dialog;
+ if (g_shell_config)
+ g_shell_config->write(fluid_prefs, FD_STORE_USER);
g_layout_list.write(fluid_prefs, FD_STORE_USER);
undo_clear();
@@ -742,6 +850,7 @@ void exit_cb(Fl_Widget *,void *) {
// and cleans up editor tmp files. Then remove fluid tmpdir /last/.
g_project.reset();
ExternalCodeEditor::tmpdir_clear();
+ delete_tmpdir();
exit(0);
}
@@ -989,15 +1098,6 @@ void apple_open_cb(const char *c) {
}
#endif // __APPLE__
-// make sure that a path nae ends with a forward slash
-static Fl_String end_with_slash(const Fl_String &str) {
- char last = str[str.size()-1];
- if (last !='/' && last != '\\')
- return str + "/";
- else
- return str;
-}
-
/**
Get the absolute path of the project file, for example `/Users/matt/dev/`.
*/
@@ -1585,10 +1685,7 @@ Fl_Menu_Item Main_Menu[] = {
{"Dialog", 0, select_layout_preset_cb, (void*)1, FL_MENU_RADIO },
{"Toolbox", 0, select_layout_preset_cb, (void*)2, FL_MENU_RADIO },
{0},
-{"&Shell",0,0,0,FL_SUBMENU},
- {"Execute &Command...",FL_ALT+'x',(Fl_Callback *)show_shell_window},
- {"Execute &Again...",FL_ALT+'g',(Fl_Callback *)do_shell_command},
- {0},
+{"&Shell", 0, Fd_Shell_Command_List::menu_marker, (void*)Fd_Shell_Command_List::default_menu, FL_SUBMENU_POINTER},
{"&Help",0,0,0,FL_SUBMENU},
{"&Rapid development with FLUID...",0,help_cb},
{"&FLTK Programmers Manual...",0,manual_cb, 0, FL_MENU_DIVIDER},
@@ -1710,7 +1807,6 @@ void make_main_window() {
fluid_prefs.get("show_guides", show_guides, 1);
fluid_prefs.get("show_restricted", show_restricted, 1);
fluid_prefs.get("show_comments", show_comments, 1);
- shell_prefs_get();
make_shell_window();
}
@@ -1740,6 +1836,9 @@ void make_main_window() {
if (!batch_mode) {
load_history();
+ g_shell_config = new Fd_Shell_Command_List;
+ // TODO: load example commands if this is the very first time we use this
+// g_shell_config->restore_defaults();
make_settings_window();
}
}
@@ -1851,6 +1950,7 @@ void set_filename(const char *c) {
set_modflag(modflag);
}
+
/**
Set the "modified" flag and update the title of the main window.
@@ -2044,6 +2144,8 @@ int main(int argc,char **argv) {
main_window->show(argc,argv);
toggle_widgetbin_cb(0,0);
toggle_sourceview_cb(0,0);
+ if (g_shell_config)
+ g_shell_config->read(fluid_prefs, FD_STORE_USER);
g_layout_list.read(fluid_prefs, FD_STORE_USER);
if (!c && openlast_button->value() && absolute_history[0][0]) {
// Open previous file when no file specified...
diff --git a/fluid/fluid.h b/fluid/fluid.h
index 024dc61ff..402194edd 100644
--- a/fluid/fluid.h
+++ b/fluid/fluid.h
@@ -28,6 +28,8 @@
#define MENUHEIGHT 25
#define WINHEIGHT (BROWSERHEIGHT+MENUHEIGHT)
+// ---- types
+
class Fl_Double_Window;
class Fl_Window;
class Fl_Menu_Bar;
@@ -36,6 +38,19 @@ class Fl_Choice;
class Fl_Button;
class Fl_Check_Button;
+/**
+ Indicate the storage location for tools like layout suites and shell macros.
+ \see class Fd_Shell_Command, class Fd_Layout_Suite
+ */
+typedef enum {
+ FD_STORE_INTERNAL, ///< stored inside FLUID app
+ FD_STORE_USER, ///< suite is stored in the user wide FLUID settings
+ FD_STORE_PROJECT, ///< suite is stored within the current .fl project file
+ FD_STORE_FILE ///< store suite in external file
+} Fd_Tool_Store;
+
+// ---- global variables
+
extern int force_parent;
extern Fl_Preferences fluid_prefs;
@@ -71,9 +86,6 @@ extern Fl_Check_Button *guides_button;
extern int modflag;
-extern void enter_project_dir();
-extern void leave_project_dir();
-
extern int update_file; // fluid -u
extern int compile_file; // fluid -c
extern int compile_strings; // fluic -cs
@@ -81,7 +93,11 @@ extern int batch_mode;
extern int pasteoffset;
-// ---- project settings
+extern Fl_String g_code_filename_arg;
+extern Fl_String g_header_filename_arg;
+extern Fl_String g_launch_path;
+
+// ---- project class declaration
class Fluid_Project {
public:
@@ -123,16 +139,15 @@ public:
extern Fluid_Project g_project;
-extern Fl_String g_code_filename_arg;
-extern Fl_String g_header_filename_arg;
-extern Fl_String g_launch_path;
-
-
// ---- public functions
+extern void enter_project_dir();
+extern void leave_project_dir();
extern void set_filename(const char *c);
extern void set_modflag(int mf, int mfc=-1);
+extern const Fl_String &get_tmpdir();
+
// ---- public callback functions
extern void save_cb(Fl_Widget *, void *v);
diff --git a/fluid/pixmaps/fd_project.png b/fluid/pixmaps/fd_project.png
new file mode 100644
index 000000000..6288496c0
--- /dev/null
+++ b/fluid/pixmaps/fd_project.png
Binary files differ
diff --git a/fluid/pixmaps/fd_user.png b/fluid/pixmaps/fd_user.png
new file mode 100644
index 000000000..503cc54a2
--- /dev/null
+++ b/fluid/pixmaps/fd_user.png
Binary files differ
diff --git a/fluid/shell_command.cxx b/fluid/shell_command.cxx
index cd764ca24..c557c6e54 100644
--- a/fluid/shell_command.cxx
+++ b/fluid/shell_command.cxx
@@ -1,7 +1,7 @@
//
// FLUID main entry for the Fast Light Tool Kit (FLTK).
//
-// Copyright 1998-2021 by Bill Spitzak and others.
+// Copyright 1998-2023 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@@ -14,125 +14,122 @@
// https://www.fltk.org/bugs.php
//
+// in progress:
+// FLUID comes with example shell commands to build the current project file
+// and run the project. This is accomplished by calling `fltk-config` on the
+// files generated by FLUID, and by calling the executable directly.
+//
+// If the user wants more complex commands, he can add or modify them in the
+// "Shell" settings panel. Modified shell commands are saved with the .fl
+// file.
+
+// The Shell panel has a list of shell commands in the upper half. Under the
+// list are buttons to add, duplicate, and delete shell commands. A popup
+// menu offers import and export functionality and a list of sample scripts.
+// We may want to add up and down buttons, so the user can change the
+// order of commands.
+
+// Selecting any shell command in the list fills in and activates a list of
+// options in the lower half of the panel. Those settings are:
+// - Name: the name of the shell command in the list
+// - Label: the label in the pulldown menu (could be the same as name?)
+// - Shortcut: shortcut key to launch the command
+// - Storage: where to store this shell command
+// - Condition: pulldown menu to make the entry conditional for various
+// target platforms, for example, a "Windows only" entry would only be added
+// to the Shell menu on a Windows machine. Other options could be:
+// - Linux only, macOS only, never (to make a list header!?), inactive?
+// - Command: a multiline input for the actual shell command
+// - Variables: a pulldown menu that insert variable names like $<sourcefile>
+// - options to save project, code, and strings before running
+// - test-run button
+
+// TODO: add @APPDIR@?
+// TODO: get a macro to find `fltk-config` @FLTK_CONFIG@
+// TODO: add an input field so the user can insert their preferred file and path for fltk-config (user setting)
+// `fltk-config` is actually tricky to find
+// for live builds, we could check the program launch directory
+// if we know where build/Xcode/bin/Debug/fluid is, we
+// may or may not find ./build/Xcode/fltk-config
+// on macOS with homebrew, we find /opt/homebrew/bin/fltk-config but the user
+// can set their own install path.
+// We can query the shell path, but that requires knowing the users shell (echo $SHELL).
+// We can run the shell as a login shell with `-l`, so the user $PTH is set: /bin/bash -l -c 'fltk-config'
+// The shell should output the path of the fltk-config that it found and why it is using that one.
+// This can also output the fltk-config version.
+// TODO: add a bunch of sensible sample shell commands
+// TODO: when this new feature is used for the very first time, import two or three samples as initial user setting
+// TODO: make the settings dialog resizable
+// TODO: make g_shell_config static, not a pointer, but don't load anything in batch mode
+
+// FEATURE: Fd_Tool_Store icons are currently redundant with @file and @save and could be improved
+// FEATURE: hostname, username, getenv support?
+// FEATURE: ad the files ./fluid.prefs and ./fluid.user.prefs as tool locations
+
+/*
+ Some ideas:
+
+ default shell is in $SHELL on linux and macOS
+
+ On macOS, we can write Apple Scripts:
+
+ #!/usr/bin/env osascript
+ say "@BASENAME@"
+
+ osascript <<EOD
+ say "spark"
+ EOD
+
+ osascript <<EOD
+ tell application "Xcode"
+ build workspace document 1
+ end tell
+ EOD
+ */
+
#include "shell_command.h"
#include "fluid.h"
+#include "file.h"
#include "alignment_panel.h"
#include <FL/Fl_Double_Window.H>
+#include <FL/Fl_Menu_Bar.H>
#include <FL/fl_message.H>
#include <FL/fl_string_functions.h>
#include <errno.h>
+static Fl_String fltk_config_cmd;
static Fl_Process s_proc;
-/// Shell settings in the .fl file
-Shell_Settings shell_settings_windows = { };
-Shell_Settings shell_settings_linux = { };
-Shell_Settings shell_settings_macos = { };
-
-/// Current shell command, stored in .fl file for each platform, and in app prefs
-Fl_String g_shell_command;
-
-/// Save .fl file before running, stored in .fl file for each platform, and in app prefs
-int g_shell_save_fl = 1;
-
-/// Save code file before running, stored in .fl file for each platform, and in app prefs
-int g_shell_save_code = 1;
-
-/// Save strings file before running, stored in .fl file for each platform, and in app prefs
-int g_shell_save_strings = 0;
-
-/// Use these settings from .fl files, stored in app prefs
-int g_shell_use_fl_settings = 1;
-/**
- Read the default shell settings from the app preferences.
+/** \class Fl_Process
+ Launch an external shell command.
*/
-void shell_prefs_get()
-{
- fluid_prefs.get("shell_command", g_shell_command, "echo \"Custom Shell Command\"");
- fluid_prefs.get("shell_savefl", g_shell_save_fl, 1);
- fluid_prefs.get("shell_writecode", g_shell_save_code, 1);
- fluid_prefs.get("shell_writemsgs", g_shell_save_strings, 0);
- fluid_prefs.get("shell_use_fl", g_shell_use_fl_settings, 1);
-}
/**
- Write the current shell settings to the app preferences.
+ Create a process manager
*/
-void shell_prefs_set()
-{
- fluid_prefs.set("shell_command", g_shell_command);
- fluid_prefs.set("shell_savefl", g_shell_save_fl);
- fluid_prefs.set("shell_writecode", g_shell_save_code);
- fluid_prefs.set("shell_writemsgs", g_shell_save_strings);
- fluid_prefs.set("shell_use_fl", g_shell_use_fl_settings);
+Fl_Process::Fl_Process() {
+ _fpt= NULL;
}
/**
- Copy shell settings from the .fl buffer if use_fl_settings is set.
+ Destroy the project manager.
*/
-void shell_settings_read()
-{
- if (g_shell_use_fl_settings==0)
- return;
-#if defined(_WIN32)
- Shell_Settings &shell_settings = shell_settings_windows;
-#elif defined(__APPLE__)
- Shell_Settings &shell_settings = shell_settings_macos;
-#else
- Shell_Settings &shell_settings = shell_settings_linux;
-#endif
- g_shell_command = shell_settings.command;
- g_shell_save_fl = ((shell_settings.flags&1)==1);
- g_shell_save_code = ((shell_settings.flags&2)==2);
- g_shell_save_strings = ((shell_settings.flags&4)==4);
+Fl_Process::~Fl_Process() {
+ // TODO: check what we need to do if a task is still running
+ if (_fpt) close();
}
/**
- Copy current shell settings to the .fl buffer if use_fl_settings is set.
- */
-void shell_settings_write()
-{
- if (g_shell_use_fl_settings==0)
- return;
-#if defined(_WIN32)
- Shell_Settings &shell_settings = shell_settings_windows;
-#elif defined(__APPLE__)
- Shell_Settings &shell_settings = shell_settings_macos;
-#else
- Shell_Settings &shell_settings = shell_settings_linux;
-#endif
- if (shell_settings.command)
- free((void*)shell_settings.command);
- shell_settings.command = NULL;
- if (!g_shell_command.empty())
- shell_settings.command = fl_strdup(g_shell_command.c_str());
- shell_settings.flags = 0;
- if (g_shell_save_fl)
- shell_settings.flags |= 1;
- if (g_shell_save_code)
- shell_settings.flags |= 2;
- if (g_shell_save_strings)
- shell_settings.flags |= 4;
-}
+ Open a process.
-/** \class Fl_Process
- \todo Explain.
+ \param[in] cmd the shell command that we want to run
+ \param[in] mode "r" or "w" for creating a stream that can read or write
+ \return a stream that is redirected from the shell command stdout
*/
-
-Fl_Process::Fl_Process() {
- _fpt= NULL;
-}
-
-Fl_Process::~Fl_Process() {
- if (_fpt) close();
-}
-
-// FIXME: popen needs the UTF-8 equivalent fl_popen
-// portable open process:
FILE * Fl_Process::popen(const char *cmd, const char *mode) {
#if defined(_WIN32) && !defined(__CYGWIN__)
// PRECONDITIONS
@@ -174,6 +171,9 @@ FILE * Fl_Process::popen(const char *cmd, const char *mode) {
#endif
}
+/**
+ Close the current process.
+ */
int Fl_Process::close() {
#if defined(_WIN32) && !defined(__CYGWIN__)
if (_fpt) {
@@ -192,11 +192,22 @@ int Fl_Process::close() {
#endif
}
-// non-null if file is open
+/**
+ non-null if file is open.
+
+ \return the current file descriptor of the process' stdout
+ */
FILE *Fl_Process::desc() const {
return _fpt;
}
+/**
+ Receive a single line from the current process.
+
+ \param[out] line buffer to receive the line
+ \param[in] s size of the provided buffer
+ \return NULL if an error occurred, otherwise a pointer to the string
+ */
char *Fl_Process::get_line(char * line, size_t s) const {
return _fpt ? fgets(line, (int)s, _fpt) : NULL;
}
@@ -237,31 +248,33 @@ void Fl_Process::clean_close(HANDLE& h) {
#endif
+/**
+ Prepare FLUID for running a shell command according to the command flags.
-// Shell command support...
-
-static bool prepare_shell_command() {
+ \param[in] flags set various flags to save the project, code, and string before running the command
+ \return false if the previous command is still running
+ */
+static bool prepare_shell_command(int flags) {
// settings_window->hide();
if (s_proc.desc()) {
fl_alert("Previous shell command still running!");
return false;
}
- if (g_shell_command.empty()) {
- fl_alert("No shell command entered!");
- return false;
- }
- if (g_shell_save_fl) {
+ if (flags & Fd_Shell_Command::SAVE_PROJECT) {
save_cb(0, 0);
}
- if (g_shell_save_code) {
+ if (flags & Fd_Shell_Command::SAVE_SOURCECODE) {
write_code_files();
}
- if (g_shell_save_strings) {
+ if (flags & Fd_Shell_Command::SAVE_STRINGS) {
write_strings_cb(0, 0);
}
return true;
}
+/**
+ Called by the file handler when the command is finished.
+ */
void shell_proc_done() {
shell_run_terminal->append("... END SHELL COMMAND ...\n");
shell_run_button->activate();
@@ -293,8 +306,56 @@ void shell_pipe_cb(FL_SOCKET, void*) {
}
}
-void do_shell_command(Fl_Return_Button*, void*) {
- if (!prepare_shell_command()) return;
+/** Find the script `fltk-config` that most closely relates to this version of FLUID.
+ This is not implemented yet.
+ */
+//static void find_fltk_config() {
+//
+//}
+
+static void expand_macro(Fl_String &cmd, const Fl_String &macro, const Fl_String &content) {
+ for (int i=0;;) {
+ i = cmd.find(macro, i);
+ if (i==Fl_String::npos) break;
+ cmd.replace(i, macro.size(), content);
+ }
+}
+
+static void expand_macros(Fl_String &cmd) {
+ expand_macro(cmd, "@BASENAME@", g_project.basename());
+ expand_macro(cmd, "@PROJECTFILE_PATH@", g_project.projectfile_path());
+ expand_macro(cmd, "@PROJECTFILE_NAME@", g_project.projectfile_name());
+ expand_macro(cmd, "@CODEFILE_PATH@", g_project.codefile_path());
+ expand_macro(cmd, "@CODEFILE_NAME@", g_project.codefile_name());
+ expand_macro(cmd, "@HEADERFILE_PATH@", g_project.headerfile_path());
+ expand_macro(cmd, "@HEADERFILE_NAME@", g_project.headerfile_name());
+ expand_macro(cmd, "@TEXTFILE_PATH@", g_project.stringsfile_path());
+ expand_macro(cmd, "@TEXTFILE_NAME@", g_project.stringsfile_name());
+// TODO: implement finding the script `fltk-config` for all platforms
+// if (cmd.find("@FLTK_CONFIG@") != Fl_String::npos) {
+// find_fltk_config();
+// expand_macro(cmd, "@FLTK_CONFIG@", fltk_config_cmd.c_str());
+// }
+ if (cmd.find("@TMPDIR@") != Fl_String::npos)
+ expand_macro(cmd, "@TMPDIR@", get_tmpdir());
+}
+
+/**
+ Prepare for and run a shell command.
+
+ \param[in] cmd the command that is sent to `/bin/sh -c ...` or `cmd.exe` on Windows machines
+ \param[in] flags various flags in preparation of the command
+ */
+void run_shell_command(const Fl_String &cmd, int flags) {
+ if (cmd.empty()) {
+ fl_alert("No shell command entered!");
+ return;
+ }
+
+ if (!prepare_shell_command(flags)) return;
+
+ Fl_String expanded_cmd = cmd;
+ expand_macros(expanded_cmd);
if (!shell_run_window->visible()) {
Fl_Preferences pos(fluid_prefs, "shell_run_Window_pos");
@@ -310,10 +371,10 @@ void do_shell_command(Fl_Return_Button*, void*) {
}
// Show the output window and clear things...
- shell_run_terminal->printf("\033[0;32m%s\033[0m\n", g_shell_command.c_str());
- shell_run_window->label(g_shell_command.c_str());
+ shell_run_terminal->printf("\033[0;32m%s\033[0m\n", expanded_cmd.c_str());
+ shell_run_window->label(expanded_cmd.c_str());
- if (s_proc.popen((char *)g_shell_command.c_str()) == NULL) {
+ if (s_proc.popen((char *)expanded_cmd.c_str()) == NULL) {
shell_run_terminal->printf("\033[1;31mUnable to run shell command: %s\033[0m\n",
strerror(errno));
shell_run_window->label("FLUID Shell");
@@ -329,28 +390,553 @@ void do_shell_command(Fl_Return_Button*, void*) {
}
/**
- Show a dialog box to run an external shell command.
+ Create an empty shell command structure.
+ */
+Fd_Shell_Command::Fd_Shell_Command()
+: shortcut(0),
+ storage(FD_STORE_USER),
+ condition(0),
+ flags(0),
+ shell_menu_item_(NULL)
+{
+}
+
+/**
+ Copy the aspects of a shell command dataset into a new shell command.
+
+ \param[in] rhs copy from this prototype
+ */
+Fd_Shell_Command::Fd_Shell_Command(const Fd_Shell_Command *rhs)
+: name(rhs->name),
+ label(rhs->label),
+ shortcut(rhs->shortcut),
+ storage(rhs->storage),
+ condition(rhs->condition),
+ condition_data(rhs->condition_data),
+ command(rhs->command),
+ flags(rhs->flags),
+ shell_menu_item_(NULL)
+{
+}
+
+/**
+ Create a default storage for a shell command and how it is accessible in FLUID.
+
+ \param[in] name is used as a stand-in for the command name and label
+ */
+Fd_Shell_Command::Fd_Shell_Command(const Fl_String &in_name)
+: name(in_name),
+ label(in_name),
+ shortcut(0),
+ storage(FD_STORE_USER),
+ condition(Fd_Shell_Command::ALWAYS),
+ command("echo \"Hello, FLUID!\""),
+ flags(Fd_Shell_Command::SAVE_PROJECT|Fd_Shell_Command::SAVE_SOURCECODE),
+ shell_menu_item_(NULL)
+{
+}
+
+/**
+ Create a storage for a shell command and how it is accessible in FLUID.
+
+ \param[in] in_name name of this command in the command list in the settings panel
+ \param[in] in_label label text in the main pulldown menu
+ \param[in] in_shortcut a keyboard shortcut that will also appear in the main menu
+ \param[in] in_storage storage location for this command
+ \param[in] in_condition commands can be hidden for certain platforms by setting a condition
+ \param[in] in_condition_data more details for future conditions, i.e. per user, per host, etc.
+ \param[in] in_command the shell command that we want to run
+ \param[in] in_flags some flags to tell FLUID to save the project, code, or strings before running the command
+ */
+Fd_Shell_Command::Fd_Shell_Command(const Fl_String &in_name,
+ const Fl_String &in_label,
+ Fl_Shortcut in_shortcut,
+ Fd_Tool_Store in_storage,
+ int in_condition,
+ const Fl_String &in_condition_data,
+ const Fl_String &in_command,
+ int in_flags)
+: name(in_name),
+ label(in_label),
+ shortcut(in_shortcut),
+ storage(in_storage),
+ condition(in_condition),
+ condition_data(in_condition_data),
+ command(in_command),
+ flags(in_flags),
+ shell_menu_item_(NULL)
+{
+}
+
+/**
+ Run this command now.
+
+ Will open the Shell Panel and execute the command if no other command is
+ currently running.
+ */
+void Fd_Shell_Command::run() {
+ if (!command.empty())
+ run_shell_command(command, flags);
+}
+
+/**
+ Update the shell submenu in main menu with the shortcut and a copy of the label.
+ */
+void Fd_Shell_Command::update_shell_menu() {
+ if (shell_menu_item_) {
+ const char *old_label = shell_menu_item_->label(); // can be NULL
+ const char *new_label = label.c_str(); // never NULL
+ if (!old_label || (old_label && strcmp(old_label, new_label))) {
+ if (old_label) ::free((void*)old_label);
+ shell_menu_item_->label(fl_strdup(new_label));
+ }
+ shell_menu_item_->shortcut(shortcut);
+ }
+}
+
+/**
+ Check if the set condition is met.
+
+ \return true if this command appears in the main menu
+ */
+bool Fd_Shell_Command::is_active() {
+ switch (condition) {
+ case ALWAYS: return true;
+ case NEVER: return false;
+#ifdef _WIN32
+ case MAC_ONLY: return false;
+ case UX_ONLY: return false;
+ case WIN_ONLY: return true;
+ case MAC_AND_UX_ONLY: return false;
+#elif defined(__APPLE__)
+ case MAC_ONLY: return true;
+ case UX_ONLY: return false;
+ case WIN_ONLY: return false;
+ case MAC_AND_UX_ONLY: return true;
+#else
+ case MAC_ONLY: return false;
+ case UX_ONLY: return true;
+ case WIN_ONLY: return false;
+ case MAC_AND_UX_ONLY: return true;
+#endif
+ case USER_ONLY: return false; // TODO: get user name
+ case HOST_ONLY: return false; // TODO: get host name
+ case ENV_ONLY: {
+ const char *value = fl_getenv(condition_data.c_str());
+ if (value && *value) return true;
+ return false;
+ }
+ }
+ return false;
+}
+
+void Fd_Shell_Command::read(Fl_Preferences &prefs) {
+ int tmp;
+ prefs.get("name", name, "<unnamed>");
+ prefs.get("label", label, "<no label>");
+ prefs.get("shortcut", tmp, 0);
+ shortcut = (Fl_Shortcut)tmp;
+ prefs.get("storage", tmp, -1);
+ if (tmp != -1) storage = (Fd_Tool_Store)tmp;
+ prefs.get("condition", condition, ALWAYS);
+ prefs.get("condition_data", condition_data, "");
+ prefs.get("command", command, "");
+ prefs.get("flags", flags, 0);
+}
+
+void Fd_Shell_Command::write(Fl_Preferences &prefs, bool save_location) {
+ prefs.set("name", name);
+ prefs.set("label", label);
+ if (shortcut != 0) prefs.set("shortcut", (int)shortcut);
+ if (save_location) prefs.set("storage", (int)storage);
+ if (condition != ALWAYS) prefs.set("condition", condition);
+ if (!condition_data.empty()) prefs.set("condition_data", condition_data);
+ if (!command.empty()) prefs.set("command", command);
+ if (flags != 0) prefs.set("flags", flags);
+}
+
+void Fd_Shell_Command::read(class Fd_Project_Reader *in) {
+ const char *c = in->read_word(1);
+ if (strcmp(c, "{")!=0) return; // expecting start of group
+ storage = FD_STORE_PROJECT;
+ for (;;) {
+ c = in->read_word(1);
+ if (strcmp(c, "}")==0) break; // end of command list
+ else if (strcmp(c, "name")==0)
+ name = in->read_word();
+ else if (strcmp(c, "label")==0)
+ label = in->read_word();
+ else if (strcmp(c, "shortcut")==0)
+ shortcut = in->read_int();
+ else if (strcmp(c, "condition")==0)
+ condition = in->read_int();
+ else if (strcmp(c, "condition_data")==0)
+ condition_data = in->read_word();
+ else if (strcmp(c, "command")==0)
+ command = in->read_word();
+ else if (strcmp(c, "flags")==0)
+ flags = in->read_int();
+ else
+ in->read_word(); // skip an unknown word
+ }
+}
+
+void Fd_Shell_Command::write(class Fd_Project_Writer *out) {
+ out->write_string("\n command {");
+ out->write_string("\n name "); out->write_word(name.c_str());
+ out->write_string("\n label "); out->write_word(label.c_str());
+ if (shortcut) out->write_string("\n shortcut %d", shortcut);
+ if (condition) out->write_string("\n condition %d", condition);
+ if (!condition_data.empty()) {
+ out->write_string("\n condition_data "); out->write_word(condition_data.c_str());
+ }
+ if (!command.empty()) {
+ out->write_string("\n command "); out->write_word(command.c_str());
+ }
+ if (flags) out->write_string("\n flags %d", flags);
+ out->write_string("\n }");
+}
+
+
+/**
+ Manage a list of shell commands and their parameters.
+ */
+Fd_Shell_Command_List::Fd_Shell_Command_List()
+: list(NULL),
+ list_size(0),
+ list_capacity(0),
+ shell_menu_(NULL)
+{
+}
+
+/**
+ Release all shell commands and destroy this class.
+ */
+Fd_Shell_Command_List::~Fd_Shell_Command_List() {
+ clear();
+}
+
+/**
+ Return the shell command at the given index.
+
+ \param[in] index must be between 0 and list_size-1
+ \return a pointer to the shell command data
+ */
+Fd_Shell_Command *Fd_Shell_Command_List::at(int index) const {
+ return list[index];
+}
+
+/**
+ Clear all shell commands.
+ */
+void Fd_Shell_Command_List::clear() {
+ if (list) {
+ for (int i=0; i<list_size; i++) {
+ delete list[i];
+ }
+ ::free(list);
+ list_size = 0;
+ list_capacity = 0;
+ list = 0;
+ }
+}
+
+/**
+ remove all shell commands of the given storage location from the list.
+ */
+void Fd_Shell_Command_List::clear(Fd_Tool_Store storage) {
+ for (int i=list_size-1; i>=0; i--) {
+ if (list[i]->storage == storage) {
+ remove(i);
+ }
+ }
+}
- Copies the current settings into the dialog box.
+/**
+ Read shell configuration from a preferences group.
+ */
+void Fd_Shell_Command_List::read(Fl_Preferences &prefs, Fd_Tool_Store storage) {
+ // import the old shell commands from previous user settings
+ if (&fluid_prefs == &prefs) {
+ int version;
+ prefs.get("shell_commands_version", version, 0);
+ if (version == 0) {
+ int save_fl, save_code, save_strings;
+ Fd_Shell_Command *cmd = new Fd_Shell_Command();
+ cmd->storage = FD_STORE_USER;
+ cmd->name = "Sample Shell Command";
+ cmd->label = "Sample Shell Command";
+ cmd->shortcut = FL_ALT+'g';
+ fluid_prefs.get("shell_command", cmd->command, "echo \"Sample Shell Command\"");
+ fluid_prefs.get("shell_savefl", save_fl, 1);
+ fluid_prefs.get("shell_writecode", save_code, 1);
+ fluid_prefs.get("shell_writemsgs", save_strings, 0);
+ if (save_fl) cmd->flags |= Fd_Shell_Command::SAVE_PROJECT;
+ if (save_code) cmd->flags |= Fd_Shell_Command::SAVE_SOURCECODE;
+ if (save_strings) cmd->flags |= Fd_Shell_Command::SAVE_STRINGS;
+ add(cmd);
+ }
+ version = 1;
+ prefs.set("shell_commands_version", version);
+ }
+ Fl_Preferences shell_commands(prefs, "shell_commands");
+ int n = shell_commands.groups();
+ for (int i=0; i<n; i++) {
+ Fl_Preferences cmd_prefs(shell_commands, Fl_Preferences::Name(i));
+ Fd_Shell_Command *cmd = new Fd_Shell_Command();
+ cmd->storage = FD_STORE_USER;
+ cmd->read(cmd_prefs);
+ add(cmd);
+ }
+}
- This dialog box offers a field for a command line and three check buttons
- to generate and save various files before the command is run.
+/**
+ Write shell configuration to a preferences group.
+ */
+void Fd_Shell_Command_List::write(Fl_Preferences &prefs, Fd_Tool_Store storage) {
+ Fl_Preferences shell_commands(prefs, "shell_commands");
+ shell_commands.delete_all_groups();
+ int index = 0;
+ for (int i=0; i<list_size; i++) {
+ if (list[i]->storage == FD_STORE_USER) {
+ Fl_Preferences cmd(shell_commands, Fl_Preferences::Name(index++));
+ list[i]->write(cmd);
+ }
+ }
+}
- If the fourth checkbox, "use settings in .fl design files" is checked,
- all shell settings will be store in the current .fl file, and they will
- be read and restored when the .fl is loaded again.
+/**
+ Read shell configuration from a project file.
+ */
+void Fd_Shell_Command_List::read(Fd_Project_Reader *in) {
+ const char *c = in->read_word(1);
+ if (strcmp(c, "{")!=0) return; // expecting start of group
+ clear(FD_STORE_PROJECT);
+ for (;;) {
+ c = in->read_word(1);
+ if (strcmp(c, "}")==0) break; // end of command list
+ else if (strcmp(c, "command")==0) {
+ Fd_Shell_Command *cmd = new Fd_Shell_Command();
+ add(cmd);
+ cmd->read(in);
+ } else {
+ in->read_word(); // skip an unknown group
+ }
+ }
+}
- Fluid will save different shell settings for different operating system as
- it is common that a different OS requires a different shell command.
+/**
+ Write shell configuration to a project file.
+ */
+void Fd_Shell_Command_List::write(Fd_Project_Writer *out) {
+ int n_in_project_file = 0;
+ for (int i=0; i<list_size; i++) {
+ if (list[i]->storage == FD_STORE_PROJECT)
+ n_in_project_file++;
+ }
+ if (n_in_project_file > 0) {
+ out->write_string("\nshell_commands {");
+ for (int i=0; i<list_size; i++) {
+ if (list[i]->storage == FD_STORE_PROJECT)
+ list[i]->write(out);
+ }
+ out->write_string("\n}");
+ }
+}
- Fluid comes with default shell settings. Pressing the "save as default" button
- will store the current setting in the Fluid app settings and are used for new
- designs, or if the "use settings..." box is not checked.
+/**
+ Add a previously created shell command to the end of the list.
- Fluid app settings are saved per user and per machine.
+ \param[in] cmd a pointer to the command that we want to add
*/
-void show_shell_window() {
+void Fd_Shell_Command_List::add(Fd_Shell_Command *cmd) {
+ if (list_size == list_capacity) {
+ list_capacity += 16;
+ list = (Fd_Shell_Command**)::realloc(list, list_capacity * sizeof(Fd_Shell_Command**));
+ }
+ list[list_size++] = cmd;
+}
+
+/**
+ Insert a newly created shell command at the given position in the list.
+
+ \param[in] index must be between 0 and list_size-1
+ \param[in] cmd a pointer to the command that we want to add
+ */
+void Fd_Shell_Command_List::insert(int index, Fd_Shell_Command *cmd) {
+ if (list_size == list_capacity) {
+ list_capacity += 16;
+ list = (Fd_Shell_Command**)::realloc(list, list_capacity * sizeof(Fd_Shell_Command**));
+ }
+ ::memmove(list+index+1, list+index, (list_size-index)*sizeof(Fd_Shell_Command**));
+ list_size++;
+ list[index] = cmd;
+}
+
+/**
+ Remove and delete the command at the given index.
+
+ \param[in] index must be between 0 and list_size-1
+ */
+void Fd_Shell_Command_List::remove(int index) {
+ delete list[index];
+ list_size--;
+ ::memmove(list+index, list+index+1, (list_size-index)*sizeof(Fd_Shell_Command**));
+}
+
+/**
+ This is called whenever the user clicks a shell command menu in the main menu.
+
+ \param[in] u cast tp long to get the index of the shell command
+ */
+void menu_shell_cmd_cb(Fl_Widget*, void *u) {
+ long index = (long)(fl_intptr_t)u;
+ g_shell_config->list[index]->run();
+}
+
+/**
+ This is called when the user selects the menu to edit the shell commands.
+ It pops up the setting panel at the shell settings tab.
+ */
+void menu_shell_customize_cb(Fl_Widget*, void*) {
settings_window->show();
w_settings_tabs->value(w_settings_shell_tab);
}
+/**
+ Rebuild the entire shell submenu from scratch and replace the old menu.
+ */
+void Fd_Shell_Command_List::rebuild_shell_menu() {
+ static Fl_Menu_Item *shell_submenu = NULL;
+ if (!shell_submenu)
+ shell_submenu = (Fl_Menu_Item*)main_menubar->find_item(menu_marker);
+
+ int i, j, num_active_items = 0;
+ // count the active commands
+ for (i=0; i<list_size; i++) {
+ if (list[i]->is_active()) num_active_items++;
+ }
+ // allocate a menu item array
+ Fl_Menu_Item *mi = (Fl_Menu_Item*)::calloc(num_active_items+2, sizeof(Fl_Menu_Item));
+ // set the menu item pointer for all active commands
+ for (i=j=0; i<list_size; i++) {
+ Fd_Shell_Command *cmd = list[i];
+ if (cmd->is_active()) {
+ cmd->shell_menu_item_ = mi + j;
+ mi[j].callback(menu_shell_cmd_cb);
+ mi[j].argument(i);
+ cmd->update_shell_menu();
+ j++;
+ }
+ }
+ if (j>0) mi[j-1].flags |= FL_MENU_DIVIDER;
+ mi[j].label(fl_strdup("Customize..."));
+ mi[j].shortcut(FL_ALT+'x');
+ mi[j].callback(menu_shell_customize_cb);
+ // replace the old menu array with the new one
+ Fl_Menu_Item *mi_old = shell_menu_;
+ shell_menu_ = mi;
+ shell_submenu->user_data(shell_menu_);
+ // free all resources from the old menu
+ if (mi_old && (mi_old != default_menu)) {
+ for (i=0; ; i++) {
+ const char *label = mi_old[i].label();
+ if (!label) break;
+ ::free((void*)label);
+ }
+ ::free(mi_old);
+ }
+}
+
+/**
+ Tell the settings dialog to query this list and update its GUI elements.
+ */
+void Fd_Shell_Command_List::update_settings_dialog() {
+ if (w_settings_shell_tab)
+ w_settings_shell_tab->do_callback(w_settings_shell_tab, LOAD);
+}
+
+/**
+ The default shell submenu in batch mode.
+ */
+Fl_Menu_Item Fd_Shell_Command_List::default_menu[] = {
+ { "Customize...", FL_ALT+'x', menu_shell_customize_cb },
+ { NULL }
+};
+
+/**
+ Used to find the shell submenu within the main menu tree.
+ */
+void Fd_Shell_Command_List::menu_marker(Fl_Widget*, void*) {
+ // intentionally left empty
+}
+
+/**
+ Export all selected shell commands to an external file.
+
+ Verify that g_shell_config and w_settings_shell_list are not NULL. Open a
+ file chooser and export all items that are selected in w_settings_shell_list
+ into an external file.
+ */
+void Fd_Shell_Command_List::export_selected() {
+ if (!g_shell_config || (g_shell_config->list_size == 0)) return;
+ if (!w_settings_shell_list) return;
+
+ Fl_Native_File_Chooser dialog;
+ dialog.title("Export selected shell commands:");
+ dialog.type(Fl_Native_File_Chooser::BROWSE_SAVE_FILE);
+ dialog.filter("FLUID Files\t*.flcmd\n");
+ dialog.directory(g_project.projectfile_path().c_str());
+ dialog.preset_file((g_project.basename() + ".flcmd").c_str());
+ if (dialog.show() != 0) return;
+
+ Fl_Preferences file(dialog.filename(), "flcmd.fluid.fltk.org", NULL, (Fl_Preferences::Root)(Fl_Preferences::C_LOCALE|Fl_Preferences::CLEAR));
+ Fl_Preferences shell_commands(file, "shell_commands");
+ int i, index = 0, n = w_settings_shell_list->size();
+ for (i = 0; i < n; i++) {
+ if (w_settings_shell_list->selected(i+1)) {
+ Fl_Preferences cmd(shell_commands, Fl_Preferences::Name(index++));
+ g_shell_config->list[i]->write(cmd, true);
+ }
+ }
+}
+
+/**
+ Import shell commands from an external file and add them to the list.
+
+ Verify that g_shell_config and w_settings_shell_list are not NULL. Open a
+ file chooser and import all items.
+ */
+void Fd_Shell_Command_List::import_from_file() {
+ if (!g_shell_config || (g_shell_config->list_size == 0)) return;
+ if (!w_settings_shell_list) return;
+
+ Fl_Native_File_Chooser dialog;
+ dialog.title("Import shell commands:");
+ dialog.type(Fl_Native_File_Chooser::BROWSE_FILE);
+ dialog.filter("FLUID Files\t*.flcmd\n");
+ dialog.directory(g_project.projectfile_path().c_str());
+ dialog.preset_file((g_project.basename() + ".flcmd").c_str());
+ if (dialog.show() != 0) return;
+
+ Fl_Preferences file(dialog.filename(), "flcmd.fluid.fltk.org", NULL, Fl_Preferences::C_LOCALE);
+ Fl_Preferences shell_commands(file, "shell_commands");
+ int i, n = shell_commands.groups();
+ for (i = 0; i < n; i++) {
+ Fl_Preferences cmd_prefs(shell_commands, Fl_Preferences::Name(i));
+ Fd_Shell_Command *cmd = new Fd_Shell_Command();
+ cmd->storage = FD_STORE_USER;
+ cmd->read(cmd_prefs);
+ g_shell_config->add(cmd);
+ }
+ w_settings_shell_list->do_callback(w_settings_shell_list, LOAD);
+ w_settings_shell_cmd->do_callback(w_settings_shell_cmd, LOAD);
+ w_settings_shell_toolbox->do_callback(w_settings_shell_toolbox, LOAD);
+ g_shell_config->rebuild_shell_menu();
+}
+
+/**
+ A pointer to the list of shell commands if we are not in batch mode.
+ */
+Fd_Shell_Command_List *g_shell_config = NULL;
+
diff --git a/fluid/shell_command.h b/fluid/shell_command.h
index cfd7b6579..ea39375f2 100644
--- a/fluid/shell_command.h
+++ b/fluid/shell_command.h
@@ -1,7 +1,7 @@
//
// FLUID main entry for the Fast Light Tool Kit (FLTK).
//
-// Copyright 1998-2021 by Bill Spitzak and others.
+// Copyright 1998-2023 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@@ -17,11 +17,13 @@
#ifndef _FLUID_SHELL_COMMAND_H
#define _FLUID_SHELL_COMMAND_H
-#include <stdio.h>
-#include <stdlib.h>
+#include "fluid.h"
#include <FL/Fl_String.H>
+#include <FL/Enumerations.H>
+#include <stdio.h>
+#include <stdlib.h>
#if defined(_WIN32) && !defined(__CYGWIN__)
# include <direct.h>
# include <windows.h>
@@ -33,29 +35,10 @@
# include <unistd.h>
#endif
-void show_shell_window();
-void do_shell_command(class Fl_Return_Button*, void*);
-
-typedef struct {
- char *command;
- int flags;
-} Shell_Settings;
-
-extern Shell_Settings shell_settings_windows;
-extern Shell_Settings shell_settings_linux;
-extern Shell_Settings shell_settings_macos;
-
-extern Fl_String g_shell_command;
-extern int g_shell_save_fl;
-extern int g_shell_save_code;
-extern int g_shell_save_strings;
-extern int g_shell_use_fl_settings;
-
-void shell_prefs_get();
-void shell_prefs_set();
-void shell_settings_read();
-void shell_settings_write();
+struct Fl_Menu_Item;
+class Fl_Widget;
+void run_shell_command(const Fl_String &cmd, int flags);
class Fl_Process {
public:
@@ -88,4 +71,71 @@ protected:
FILE * _fpt;
};
+class Fd_Shell_Command {
+public:
+ enum { ALWAYS, NEVER, MAC_ONLY, UX_ONLY, WIN_ONLY, MAC_AND_UX_ONLY, USER_ONLY, HOST_ONLY, ENV_ONLY }; // conditions
+ enum { SAVE_PROJECT = 1, SAVE_SOURCECODE = 2, SAVE_STRINGS = 4, SAVE_ALL = 7 }; // flags
+ Fd_Shell_Command();
+ Fd_Shell_Command(const Fd_Shell_Command *rhs);
+ Fd_Shell_Command(const Fl_String &in_name);
+ Fd_Shell_Command(const Fl_String &in_name,
+ const Fl_String &in_label,
+ Fl_Shortcut in_shortcut,
+ Fd_Tool_Store in_storage,
+ int in_condition,
+ const Fl_String &in_condition_data,
+ const Fl_String &in_command,
+ int in_flags);
+ Fl_String name;
+ Fl_String label;
+ Fl_Shortcut shortcut;
+ Fd_Tool_Store storage;
+ int condition; // always, hide, windows only, linux only, mac only, user, machine
+ Fl_String condition_data; // user name, machine name
+ Fl_String command;
+ int flags; // save_project, save_code, save_string, ...
+ Fl_Menu_Item *shell_menu_item_;
+ void run();
+ void read(Fl_Preferences &prefs);
+ void write(Fl_Preferences &prefs, bool save_location = false);
+ void read(class Fd_Project_Reader*);
+ void write(class Fd_Project_Writer*);
+ void update_shell_menu();
+ bool is_active();
+};
+
+class Fd_Shell_Command_List {
+public:
+ Fd_Shell_Command **list;
+ int list_size;
+ int list_capacity;
+ Fl_Menu_Item *shell_menu_;
+public:
+ Fd_Shell_Command_List();
+ ~Fd_Shell_Command_List();
+ Fd_Shell_Command *at(int index) const;
+ void add(Fd_Shell_Command *cmd);
+ void insert(int index, Fd_Shell_Command *cmd);
+ void remove(int index);
+ void clear();
+ void clear(Fd_Tool_Store store);
+// void move_up();
+// void move_down();
+// int load(const Fl_String &filename);
+// int save(const Fl_String &filename);
+ void read(Fl_Preferences &prefs, Fd_Tool_Store storage);
+ void write(Fl_Preferences &prefs, Fd_Tool_Store storage);
+ void read(class Fd_Project_Reader*);
+ void write(class Fd_Project_Writer*);
+ void rebuild_shell_menu();
+ void update_settings_dialog();
+
+ static Fl_Menu_Item default_menu[];
+ static void menu_marker(Fl_Widget*, void*);
+ static void export_selected();
+ static void import_from_file();
+};
+
+extern Fd_Shell_Command_List *g_shell_config;
+
#endif // _FLUID_SHELL_COMMAND_H
diff --git a/fluid/sourceview_panel.cxx b/fluid/sourceview_panel.cxx
index 2cd008f85..64d7c6b0d 100644
--- a/fluid/sourceview_panel.cxx
+++ b/fluid/sourceview_panel.cxx
@@ -87,17 +87,17 @@ void update_sourceview_cb(class Fl_Button*, void*) {
if (!sv_source_filename) {
sv_source_filename = (char*)malloc(FL_PATH_MAX);
- fluid_prefs.getUserdataPath(sv_source_filename, FL_PATH_MAX);
+ fl_strlcpy(sv_source_filename, get_tmpdir().c_str(), FL_PATH_MAX);
fl_strlcat(sv_source_filename, "source_view_tmp.cxx", FL_PATH_MAX);
}
if (!sv_header_filename) {
sv_header_filename = (char*)malloc(FL_PATH_MAX);
- fluid_prefs.getUserdataPath(sv_header_filename, FL_PATH_MAX);
+ fl_strlcpy(sv_header_filename, get_tmpdir().c_str(), FL_PATH_MAX);
fl_strlcat(sv_header_filename, "source_view_tmp.h", FL_PATH_MAX);
}
if (!sv_design_filename) {
sv_design_filename = (char*)malloc(FL_PATH_MAX);
- fluid_prefs.getUserdataPath(sv_design_filename, FL_PATH_MAX);
+ fl_strlcpy(sv_design_filename, get_tmpdir().c_str(), FL_PATH_MAX);
fl_strlcat(sv_design_filename, "source_view_tmp.fl", FL_PATH_MAX);
}
@@ -108,8 +108,9 @@ void update_sourceview_cb(class Fl_Button*, void*) {
sv_project->scroll(top, 0);
} else if (sv_strings->visible_r()) {
static const char *exts[] = { ".txt", ".po", ".msg" };
- char fn[FL_PATH_MAX];
- fluid_prefs.getUserdataPath(fn, FL_PATH_MAX);
+ char fn[FL_PATH_MAX+1];
+ fl_strlcpy(fn, get_tmpdir().c_str(), FL_PATH_MAX);
+ fl_strlcat(fn, "strings", FL_PATH_MAX);
fl_filename_setext(fn, FL_PATH_MAX, exts[g_project.i18n_type]);
write_strings(fn);
int top = sv_strings->top_line();
diff --git a/fluid/sourceview_panel.fl b/fluid/sourceview_panel.fl
index e78224677..61f6242a9 100644
--- a/fluid/sourceview_panel.fl
+++ b/fluid/sourceview_panel.fl
@@ -102,17 +102,17 @@ and load those into the Code Viewer widgets.} open return_type void
if (!sv_source_filename) {
sv_source_filename = (char*)malloc(FL_PATH_MAX);
- fluid_prefs.getUserdataPath(sv_source_filename, FL_PATH_MAX);
+ fl_strlcpy(sv_source_filename, get_tmpdir().c_str(), FL_PATH_MAX);
fl_strlcat(sv_source_filename, "source_view_tmp.cxx", FL_PATH_MAX);
}
if (!sv_header_filename) {
sv_header_filename = (char*)malloc(FL_PATH_MAX);
- fluid_prefs.getUserdataPath(sv_header_filename, FL_PATH_MAX);
+ fl_strlcpy(sv_header_filename, get_tmpdir().c_str(), FL_PATH_MAX);
fl_strlcat(sv_header_filename, "source_view_tmp.h", FL_PATH_MAX);
}
if (!sv_design_filename) {
sv_design_filename = (char*)malloc(FL_PATH_MAX);
- fluid_prefs.getUserdataPath(sv_design_filename, FL_PATH_MAX);
+ fl_strlcpy(sv_design_filename, get_tmpdir().c_str(), FL_PATH_MAX);
fl_strlcat(sv_design_filename, "source_view_tmp.fl", FL_PATH_MAX);
}
@@ -123,8 +123,9 @@ and load those into the Code Viewer widgets.} open return_type void
sv_project->scroll(top, 0);
} else if (sv_strings->visible_r()) {
static const char *exts[] = { ".txt", ".po", ".msg" };
- char fn[FL_PATH_MAX];
- fluid_prefs.getUserdataPath(fn, FL_PATH_MAX);
+ char fn[FL_PATH_MAX+1];
+ fl_strlcpy(fn, get_tmpdir().c_str(), FL_PATH_MAX);
+ fl_strlcat(fn, "strings", FL_PATH_MAX);
fl_filename_setext(fn, FL_PATH_MAX, exts[g_project.i18n_type]);
write_strings(fn);
int top = sv_strings->top_line();
diff --git a/src/Fl_Preferences.cxx b/src/Fl_Preferences.cxx
index 93b29db45..c7a47881f 100644
--- a/src/Fl_Preferences.cxx
+++ b/src/Fl_Preferences.cxx
@@ -233,7 +233,9 @@ Fl_Preferences::Root Fl_Preferences::filename( char *buffer, size_t buffer_size,
<tt>\<null\>/Library/Preferences/\$(vendor)/\$(application).prefs</tt>,
which would silently fail to create a preference file.
- \param[in] root can be \c USER_L or \c SYSTEM_L for user specific or system wide preferences
+ \param[in] root can be \c USER_L or \c SYSTEM_L for user specific or system
+ wide preferences, add the CLEAR flag to start with a clean set of
+ preferences instead of reading them from the database
\param[in] vendor unique text describing the company or author of this file, must be a valid filepath segment
\param[in] application unique text describing the application, must be a valid filepath segment
@@ -246,19 +248,41 @@ Fl_Preferences::Fl_Preferences( Root root, const char *vendor, const char *appli
}
/**
- \brief Use this constructor to create or read a preference file at an
- arbitrary position in the file system.
+ \brief Deprecated: Use this constructor to create or read a preference file at an
+ arbitrary position in the file system.
+
+ This constructor should no longer be used because the generated database uses
+ the current locale, making it impossible to exchange floating point settings
+ between machines with different language settings.
- The file name is generated in the form <tt>\$(path)/\$(application).prefs</tt>.
- If \p application is \c NULL, \p path is taken literally as the file path and name.
+ Use `Fl_Preferences(path, vendor, application, C_LOCALE)` in new projects and
+ `Fl_Preferences(path, vendor, application, 0)` if you must keep backward
+ compatibility.
- \param[in] path path to the directory that contains the preference file
- \param[in] vendor unique text describing the company or author of this file, must be a valid filepath segment
- \param[in] application unique text describing the application, must be a valid filepath segment
+ \see Fl_Preferences( const char *path, const char *vendor, const char *application, Root flags )
*/
Fl_Preferences::Fl_Preferences( const char *path, const char *vendor, const char *application ) {
node = new Node( "." );
- rootNode = new RootNode( this, path, vendor, application );
+ rootNode = new RootNode( this, path, vendor, application, (Root)0 );
+ node->setRoot(rootNode);
+}
+
+/**
+ \brief Use this constructor to create or read a preference file at an
+ arbitrary position in the file system.
+
+ The file name is generated in the form <tt>\$(path)/\$(application).prefs</tt>.
+ If \p application is \c NULL, \p path is taken literally as the file path and name.
+
+ \param[in] path path to the directory that contains the preference file
+ \param[in] vendor unique text describing the company or author of this file, must be a valid filepath segment
+ \param[in] application unique text describing the application, must be a valid filename or NULL
+ \param[in] set C_LOCALE to make the preferences file independent of the current locale,
+ add the CLEAR flag to start with a clean set of preferences instead of reading from the database
+ */
+Fl_Preferences::Fl_Preferences( const char *path, const char *vendor, const char *application, Root flags ) {
+ node = new Node( "." );
+ rootNode = new RootNode( this, path, vendor, application, flags );
node->setRoot(rootNode);
}
@@ -1168,23 +1192,24 @@ Fl_Preferences::RootNode::RootNode( Fl_Preferences *prefs, Root root, const char
filename_(0L),
vendor_(0L),
application_(0L),
- root_type_(root)
+ root_type_((Root)(root & ~CLEAR))
{
char *filename = Fl::system_driver()->preference_rootnode(prefs, root, vendor, application);
filename_ = filename ? fl_strdup(filename) : 0L;
vendor_ = fl_strdup(vendor);
application_ = fl_strdup(application);
- read();
+ if ( (root & CLEAR) == 0 )
+ read();
}
// create the root node
// - construct the name of the file that will hold our preferences
-Fl_Preferences::RootNode::RootNode( Fl_Preferences *prefs, const char *path, const char *vendor, const char *application )
+Fl_Preferences::RootNode::RootNode( Fl_Preferences *prefs, const char *path, const char *vendor, const char *application, Root flags )
: prefs_(prefs),
filename_(0L),
vendor_(0L),
application_(0L),
- root_type_(Fl_Preferences::USER)
+ root_type_( (Root)(USER | (flags & C_LOCALE) ))
{
if (!vendor)
@@ -1199,7 +1224,8 @@ Fl_Preferences::RootNode::RootNode( Fl_Preferences *prefs, const char *path, con
}
vendor_ = fl_strdup(vendor);
application_ = fl_strdup(application);
- read();
+ if ( (flags & CLEAR) == 0 )
+ read();
}
// create a root node that exists only on RAM and can not be read or written to
diff --git a/src/filename_absolute.cxx b/src/filename_absolute.cxx
index 70b86fcf7..0d0155df1 100644
--- a/src/filename_absolute.cxx
+++ b/src/filename_absolute.cxx
@@ -367,3 +367,4 @@ Fl_String fl_getcwd() {
fl_getcwd(buffer, FL_PATH_MAX);
return Fl_String(buffer);
}
+
diff --git a/test/tree.fl b/test/tree.fl
index a48be0284..cb2c8803e 100644
--- a/test/tree.fl
+++ b/test/tree.fl
@@ -392,7 +392,7 @@ tree->clear_changed();} open
tooltip {Test tree} xywh {15 22 320 539} box DOWN_BOX color 55 selection_color 15
class Fl_Tree
} {}
- Fl_Group {} {open selected
+ Fl_Group {} {open
xywh {350 5 681 556}
code0 {o->resizable(0);}
} {
@@ -780,7 +780,7 @@ Fl::visible_focus(onoff);}
}
}
Fl_Group {} {
- label {Test Operations}
+ label {Test Operations} open selected
tooltip {These controls only affect the defaults for new items that are created. These test the Fl_Tree_Prefs methods.} xywh {350 435 330 125} box GTK_DOWN_BOX color 47 labelsize 12
} {
Fl_Group showitem_box {
@@ -847,7 +847,7 @@ tree->redraw();}
callback {const char *filename = fl_file_chooser("Select a Preferences style Database", "Preferences(*.prefs)", 0L);
if (filename) {
tree->clear();
- Fl_Preferences prefs(filename, 0L, 0L);
+ Fl_Preferences prefs(filename, 0L, 0L, Fl_Preferences::C_LOCALE);
tree->load(prefs);
tree->redraw();
}}
diff --git a/test/unittest_core.cxx b/test/unittest_core.cxx
index 6091dd7b4..ad60d172c 100644
--- a/test/unittest_core.cxx
+++ b/test/unittest_core.cxx
@@ -278,7 +278,7 @@ TEST(fl_filename, relative) {
r = fl_filename_relative("../foo.txt", base);
EXPECT_STREQ(r.c_str(), "../foo.txt");
return true;
- }
+}
TEST(fl_filename, absolute) {
Fl_String base = "/var/tmp/somedir";
@@ -293,6 +293,7 @@ TEST(fl_filename, absolute) {
return true;
}
+
bool cb1a_ok = false, cb1b_ok = false, cb1c_ok = false;
int cb1_alloc = 0;
class MyString : public Fl_String {