ARB
macro_gui.cxx
Go to the documentation of this file.
1 // ============================================================= //
2 // //
3 // File : macro_gui.cxx //
4 // Purpose : //
5 // //
6 // Coded by Ralf Westram (coder@reallysoft.de) in May 2005 //
7 // Institute of Microbiology (Technical University Munich) //
8 // http://www.arb-home.de/ //
9 // //
10 // ============================================================= //
11 
12 #include "macros.hxx"
13 #include "macros_local.hxx"
14 #include "trackers.hxx"
15 
16 #include <arbdb.h>
17 #include <arb_file.h>
18 #include <arb_match.h>
19 
20 #include <aw_window.hxx>
21 #include <aw_edit.hxx>
22 #include <aw_file.hxx>
23 #include <aw_awar.hxx>
24 #include <aw_msg.hxx>
25 #include <arbdbt.h>
26 #include <ad_cb.h>
27 
28 #define ma_assert(bed) arb_assert(bed)
29 
30 #define AWAR_MACRO_RECORDING_MACRO_TEXT AWAR_MACRO_BASE "/button_label"
31 #define AWAR_MACRO_RECORDING_EXPAND AWAR_MACRO_BASE "/expand"
32 #define AWAR_MACRO_RECORDING_RUNB4 AWAR_MACRO_BASE "/runb4"
33 #define AWAR_MACRO_INTERRUPT_PROMPT AWAR_MACRO_BASE "/" NEVER_RECORDED_ID "/prompt"
34 
35 static void delete_macro_cb(AW_window *aww) {
36  AW_root *awr = aww->get_root();
37  char *macroName = AW_get_selected_fullname(awr, AWAR_MACRO_BASE);
38 
39  if (GB_unlink(macroName)<0) aw_message(GB_await_error());
41 
42  free(macroName);
43 }
44 
45 static void macro_execution_finished(AW_root *awr, char *macroName) {
46 #if defined(DEBUG)
47  fprintf(stderr, "macro_execution_finished(%s)\n", macroName);
48 #endif
49 
50  AW_set_selected_fullname(awr, AWAR_MACRO_BASE, macroName); // reset selected macro (needed if macro calls other macro(s))
51 
52  free(macroName);
53 }
54 
55 static void exec_macro_cb(AW_window *aww, bool loop_marked) {
56  AW_root *awr = aww->get_root();
57  char *macroName = AW_get_selected_fullname(awr, AWAR_MACRO_BASE); // @@@ instead use function returning plain name w/o dir
58  GB_ERROR error = getMacroRecorder(awr)->execute(macroName, loop_marked, makeRootCallback(macro_execution_finished, macroName));
59  if (error) {
60  aw_message(error);
61  free(macroName); // only free in error-case (see macro_execution_finished)
62  }
63 }
64 
66  awr->awar(AWAR_MACRO_RECORDING_MACRO_TEXT)->write_string(awr->is_tracking() ? "STOP" : "RECORD");
67 }
68 
69 static void start_macro_cb(AW_window *aww) {
70  AW_root *awr = aww->get_root();
72 
73  if (awr->is_tracking()) {
74  error = getMacroRecorder(awr)->stop_recording();
75  }
76  else {
77  bool expand = awr->awar(AWAR_MACRO_RECORDING_EXPAND)->read_int();
78  bool runb4 = expand && awr->awar(AWAR_MACRO_RECORDING_RUNB4)->read_int();
79 
80  char *macroName = AW_get_selected_fullname(awr, AWAR_MACRO_BASE);
81  if (GB_is_directory(macroName)) {
82  error = "Please specify name of macro to record";
83  }
84  else {
85  if (runb4) exec_macro_cb(aww, false);
86 
88  error = getMacroRecorder(awr)->start_recording(macroName, sac, expand);
89  free(sac);
90  }
91  free(macroName);
92  }
93 
96  if (error) aw_message(error);
97 }
98 
100  AW_root *awr = aww->get_root();
101  GB_ERROR error = NULp;
102 
103  if (!awr->is_tracking()) {
104  error = "Only possible while recording macro.";
105  }
106  else {
107  const char *text = awr->awar(AWAR_MACRO_INTERRUPT_PROMPT)->read_char_pntr();
108  char *info = GBS_regreplace(text, "/\\s* //", &error);
109 
110  if (!error) {
111  if (info[0] == 0) {
112  error = "Please insert some text as user prompt";
113  }
114  else {
116  }
117  }
118 
119  free(info);
120  }
121 
122  aw_message_if(error);
123 }
124 
126  AW_root *awr = aww->get_root();
127  if (!awr->is_tracking()) {
128  aw_message("Note: this will only work while recording a macro!");
129  }
130 
131  static AW_window_simple *aws = NULp;
132  if (!aws) {
133  aws = new AW_window_simple;
134 
135  aws->init(awr, "DEFINE_INTERRUPTION", "Define macro interruption");
136  aws->load_xfig("macro_interruption.fig");
137 
138  aws->at("close"); aws->callback(AW_POPDOWN);
139  aws->create_button(NEVER_RECORDED_ID "CLOSE", "CLOSE", "C");
140 
141  aws->at("help"); aws->callback(makeHelpCallback("macro_interruption.hlp"));
142  aws->create_button(NEVER_RECORDED_ID "HELP", "HELP", "H");
143 
144  aws->at("box");
145  aws->create_text_field(AWAR_MACRO_INTERRUPT_PROMPT);
146 
147  aws->at("add");
148  aws->callback(insert_interruption_to_macro_cb);
149  aws->create_autosize_button(NEVER_RECORDED_ID "Add", ".. and interrupt playback until user presses 'continue'");
150  }
151 
152  aws->activate();
153 }
154 
155 static void edit_macro_cb(AW_window *aww) {
156  char *path = AW_get_selected_fullname(aww->get_root(), AWAR_MACRO_BASE);
157  AW_edit(path);
158  free(path);
159 }
160 
163 }
164 
165 static void create_macro_variables(AW_root *aw_root) {
166  AW_create_fileselection_awars(aw_root, AWAR_MACRO_BASE, ".", ".amc", "");
167  aw_root->awar_string(AWAR_MACRO_RECORDING_MACRO_TEXT, "RECORD");
171 
172  {
173  UserActionTracker *tracker = aw_root->get_tracker();
174  MacroRecorder *macroRecorder = dynamic_cast<MacroRecorder*>(tracker);
175 
176  GBDATA *gb_main = macroRecorder->get_gbmain();
177  GB_ERROR error = NULp;
178 
179  GB_transaction ta(gb_main);
180 
181  GBDATA *gb_recording = GB_searchOrCreate_int(gb_main, MACRO_TRIGGER_RECORDING, 0);
182  if (!gb_recording) error = GB_await_error();
183  else error = GB_add_callback(gb_recording, GB_CB_CHANGED, makeDatabaseCallback(macro_recording_changed_cb));
184 
185  if (error) aw_message(GBS_global_string("Failed to bind macro_recording_changed_cb (Reason: %s)", error));
186  }
187 
189 }
190 
191 static void popup_macro_window(AW_window *aww) {
192  static AW_window_simple *aws = NULp;
193  if (!aws) {
194  AW_root *aw_root = aww->get_root();
195 
196  aws = new AW_window_simple;
197  aws->init(aw_root, MACRO_WINDOW_ID, "MACROS");
198  aws->load_xfig("macro_select.fig");
199 
200  create_macro_variables(aw_root);
201 
202  aws->at("close"); aws->callback(AW_POPDOWN);
203  aws->create_button("CLOSE", "CLOSE", "C");
204 
205  aws->at("help"); aws->callback(makeHelpCallback("macro.hlp"));
206  aws->create_button("HELP", "HELP");
207 
208  aws->at("record"); aws->callback(start_macro_cb);
210 
211  aws->at("expand"); aws->create_toggle(AWAR_MACRO_RECORDING_EXPAND);
212  aws->at("runb4"); aws->create_toggle(AWAR_MACRO_RECORDING_RUNB4);
213 
214  aws->at("interrupt"); aws->callback(popup_interrupt_macro_window_cb);
215  aws->create_button(NEVER_RECORDED_ID, "Interrupt");
216 
217  aws->at("edit"); aws->callback(edit_macro_cb); aws->create_button("EDIT", "EDIT");
218  aws->at("delete"); aws->callback(delete_macro_cb); aws->create_button("DELETE", "DELETE");
219 
220  aws->at("exec");
221  aws->callback(makeWindowCallback(exec_macro_cb, false));
222  aws->create_button(MACRO_PLAYBACK_ID, "EXECUTE");
223 
224  aws->at("execWith");
225  aws->callback(makeWindowCallback(exec_macro_cb, true));
226  aws->create_autosize_button(MACRO_PLAYBACK_MARKED_ID, "Execute with each marked species");
227 
228  AW_create_fileselection(aws, AWAR_MACRO_BASE, "", "ARBMACROHOME^ARBMACRO", ANY_DIR, false);
229  }
230  aws->activate();
231 }
232 
233 void insert_macro_menu_entry(AW_window *awm, bool prepend_separator) {
234  if (getMacroRecorder(awm->get_root())) {
235  if (prepend_separator) awm->sep______________();
236  awm->insert_menu_topic("macros", "Macros ", "M", "macro.hlp", AWM_ALL, popup_macro_window);
237  }
238 }
239 
240 static void dont_announce_done(AW_root*) {}
241 
242 void execute_macro(AW_root *root, const char *macroname) {
243  // used to execute macro passed via CLI
244  GB_ERROR error = NULp;
245  {
246  // @@@ allow macro playback from client? (using server via AWAR)
247  MacroRecorder *recorder = getMacroRecorder(root);
248  if (!recorder) error = "macro playback only available in server";
249  else error = recorder->execute(macroname, false, makeRootCallback(dont_announce_done));
250  }
251 
252  if (error) {
253  aw_message(GBS_global_string("Can't execute macro '%s' (Reason: %s)", macroname, error));
254  }
255 }
const char * GB_ERROR
Definition: arb_core.h:25
GB_ERROR start_recording(const char *file, const char *stop_action_name, bool expand_existing)
Definition: trackers.cxx:74
void update_macro_record_button(AW_root *awr)
Definition: macro_gui.cxx:65
bool is_tracking() const
Definition: aw_root.hxx:179
void AW_set_selected_fullname(AW_root *awr, const char *awar_prefix, const char *to_fullname)
Definition: AW_file.cxx:940
void insert_menu_topic(const char *id, const char *name, const char *mnemonic, const char *help_text_, AW_active mask, const WindowCallback &wcb)
Definition: AW_window.cxx:595
static void popup_interrupt_macro_window_cb(AW_window *aww)
Definition: macro_gui.cxx:125
#define MACRO_WINDOW_ID
GB_ERROR GB_add_callback(GBDATA *gbd, GB_CB_TYPE type, const DatabaseCallback &dbcb)
Definition: ad_cb.cxx:356
void AW_edit(const char *path)
Definition: AW_edit.cxx:16
UserActionTracker * get_tracker()
Definition: aw_root.hxx:180
#define AWAR_MACRO_RECORDING_EXPAND
Definition: macro_gui.cxx:31
GB_ERROR execute(const char *macroFile, bool loop_marked, const RootCallback &execution_done_cb)
Definition: trackers.cxx:210
long read_int() const
Definition: AW_awar.cxx:184
const char * GBS_global_string(const char *templat,...)
Definition: arb_msg.cxx:203
char * AW_get_selected_fullname(AW_root *awr, const char *awar_prefix)
Definition: AW_file.cxx:906
MacroRecorder * getMacroRecorder(AW_root *aw_root)
Definition: trackers.hxx:146
void AW_POPDOWN(AW_window *window)
Definition: AW_window.cxx:52
char * GBS_regreplace(const char *str, const char *regReplExpr, GB_ERROR *error)
Definition: arb_match.cxx:175
char * window_defaults_name
window title
Definition: aw_window.hxx:347
int GB_unlink(const char *path)
Definition: arb_file.cxx:188
static void dont_announce_done(AW_root *)
Definition: macro_gui.cxx:240
#define AWAR_MACRO_RECORDING_RUNB4
Definition: macro_gui.cxx:32
const char * read_char_pntr() const
Definition: AW_awar.cxx:168
GB_ERROR GB_await_error()
Definition: arb_msg.cxx:342
static AW_root * SINGLETON
Definition: aw_root.hxx:102
WindowCallback makeHelpCallback(const char *helpfile)
Definition: aw_window.hxx:106
#define AWAR_MACRO_RECORDING_MACRO_TEXT
Definition: macro_gui.cxx:30
void add_planned_interruption(const char *displayed_text)
Definition: trackers.cxx:282
static void macro_recording_changed_cb()
Definition: macro_gui.cxx:161
static void insert_interruption_to_macro_cb(AW_window *aww)
Definition: macro_gui.cxx:99
static void error(const char *msg)
Definition: mkptypes.cxx:96
void AW_create_fileselection_awars(AW_root *awr, const char *awar_base, const char *directories, const char *filter, const char *file_name)
Definition: AW_file.cxx:72
GBDATA * GB_searchOrCreate_int(GBDATA *gb_container, const char *fieldpath, long default_value)
Definition: adquery.cxx:569
static void exec_macro_cb(AW_window *aww, bool loop_marked)
Definition: macro_gui.cxx:55
static void edit_macro_cb(AW_window *aww)
Definition: macro_gui.cxx:155
void execute_macro(AW_root *root, const char *macroname)
Definition: macro_gui.cxx:242
AW_awar * awar(const char *awar)
Definition: AW_root.cxx:554
static void popup_macro_window(AW_window *aww)
Definition: macro_gui.cxx:191
void AW_refresh_fileselection(AW_root *awr, const char *awar_prefix)
Definition: AW_file.cxx:944
static AW_window_menu_modes_opengl * awm
static void start_macro_cb(AW_window *aww)
Definition: macro_gui.cxx:69
static void create_macro_variables(AW_root *aw_root)
Definition: macro_gui.cxx:165
#define AWAR_MACRO_INTERRUPT_PROMPT
Definition: macro_gui.cxx:33
AW_awar * awar_int(const char *var_name, long default_value=0, AW_default default_file=AW_ROOT_DEFAULT)
Definition: AW_root.cxx:580
#define MACRO_RECORD_ID
#define NEVER_RECORDED_ID
Definition: aw_window.hxx:117
bool GB_is_directory(const char *path)
Definition: arb_file.cxx:176
static void macro_execution_finished(AW_root *awr, char *macroName)
Definition: macro_gui.cxx:45
#define MACRO_TRIGGER_RECORDING
Definition: arbdbt.h:25
#define AWAR_MACRO_BASE
void aw_message(const char *msg)
Definition: AW_status.cxx:1142
void insert_macro_menu_entry(AW_window *awm, bool prepend_separator)
Definition: macro_gui.cxx:233
AW_root * get_root()
Definition: aw_window.hxx:359
#define NULp
Definition: cxxforward.h:116
GB_ERROR stop_recording()
Definition: trackers.cxx:91
void AW_create_fileselection(AW_window *aws, const char *awar_prefix, const char *at_prefix, const char *pwd, DirDisplay disp_dirs, bool allow_wildcards)
Definition: AW_file.cxx:870
GB_ERROR write_string(const char *aw_string)
void sep______________()
Definition: AW_window.cxx:753
static void delete_macro_cb(AW_window *aww)
Definition: macro_gui.cxx:35
GBDATA * get_gbmain()
Definition: trackers.hxx:66
GB_transaction ta(gb_var)
GBDATA * gb_main
Definition: adname.cxx:32
AW_awar * awar_string(const char *var_name, const char *default_value="", AW_default default_file=AW_ROOT_DEFAULT)
Definition: AW_root.cxx:570
#define MACRO_PLAYBACK_MARKED_ID
static int info[maxsites+1]
#define MACRO_PLAYBACK_ID
void aw_message_if(GB_ERROR error)
Definition: aw_msg.hxx:21
char * GBS_global_string_copy(const char *templat,...)
Definition: arb_msg.cxx:194