source: tags/old_import_filter/WINDOW/AW_modal.cxx

Last change on this file was 8772, checked in by westram, 12 years ago
  • removed label and mnemonic params from create_selection_list
    • labels do not make much sense anyway (and were hidden behind the list up to now)
    • added assertion versus using labels with selection lists
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 27.0 KB
Line 
1// ================================================================ //
2//                                                                  //
3//   File      : AW_modal.cxx                                       //
4//   Purpose   : Modal dialogs                                      //
5//                                                                  //
6//   Institute of Microbiology (Technical University Munich)        //
7//   http://www.arb-home.de/                                        //
8//                                                                  //
9// ================================================================ //
10
11#include <aw_window.hxx>
12#include <aw_global.hxx>
13#include <aw_file.hxx>
14#include <aw_awar.hxx>
15#include "aw_root.hxx"
16#include "aw_question.hxx"
17#include "aw_advice.hxx"
18#include "aw_msg.hxx"
19#include "aw_select.hxx"
20
21#include <arbdbt.h>
22#include <arb_strarray.h>
23
24#include <deque>
25#include <string>
26#include <algorithm>
27
28using namespace std;
29
30#define AWAR_QUESTION "tmp/question"
31
32#define AW_MESSAGE_LISTEN_DELAY 500 // look in ms whether a father died
33
34static int aw_message_cb_result;
35
36void message_cb(AW_window *, AW_CL cd1) {
37    long result = (long)cd1;
38    if (result == -1) { // exit
39        exit(EXIT_FAILURE);
40    }
41    aw_message_cb_result = ((int)result);
42    return;
43}
44
45static void aw_message_timer_listen_event(AW_root *awr, AW_CL cl1, AW_CL cl2)
46{
47#if defined(TRACE_STATUS_MORE)
48    fprintf(stderr, "in aw_message_timer_listen_event\n"); fflush(stdout);
49#endif // TRACE_STATUS_MORE
50
51    AW_window *aww = ((AW_window *)cl1);
52    if (aww->is_shown()) {
53        awr->add_timed_callback_never_disabled(AW_MESSAGE_LISTEN_DELAY, aw_message_timer_listen_event, cl1, cl2);
54    }
55}
56
57// --------------------
58//      aw_question
59
60void AW_reactivate_all_questions() {
61    GB_transaction  ta(AW_ROOT_DEFAULT);
62    GBDATA         *gb_neverAskedAgain = GB_search(AW_ROOT_DEFAULT, "answers", GB_FIND);
63    const char     *msg                = "No questions were disabled yet.";
64
65    if (gb_neverAskedAgain) {
66        int reactivated = 0;
67        for (GBDATA *gb_q = GB_child(gb_neverAskedAgain); gb_q; gb_q = GB_nextChild(gb_q)) {
68            if (GB_read_int(gb_q)) {
69                GB_write_int(gb_q, 0);
70                reactivated++;
71            }
72        }
73        if (reactivated) {
74            msg = GBS_global_string("Reactivated %i questions (for this session)\n"
75                                    "To reactivate them for future sessions, save properties.",
76                                    reactivated);
77        }
78    }
79    aw_message(msg);
80}
81
82int aw_question(const char *uniqueID, const char *question, const char *buttons, bool fixedSizeButtons, const char *helpfile) {
83    // return 0 for first button, 1 for second button, 2 for third button, ...
84    //
85    // the single buttons are separated by commas (e.g. "YES,NO")
86    // If the button-name starts with ^ it starts a new row of buttons
87    // (if a button named 'EXIT' is pressed the program terminates using exit(EXIT_FAILURE))
88    //
89    // The remaining arguments only apply if 'buttons' is non-zero:
90    //
91    // If fixedSizeButtons is true all buttons have the same size
92    // otherwise the size for every button is set depending on the text length
93    //
94    // If 'helpfile' is non-zero a HELP button is added.
95
96    aw_assert(buttons);
97
98    AW_root *root = AW_root::SINGLETON;
99
100    char *awar_name_neverAskAgain = NULL;
101    int   have_auto_answer        = 0;
102
103    if (uniqueID) {
104        GB_ERROR error = GB_check_key(uniqueID);
105        if (error) {
106            aw_message(error);
107            uniqueID = NULL;
108        }
109        else {
110            awar_name_neverAskAgain     = GBS_global_string_copy("answers/%s", uniqueID);
111            AW_awar *awar_neverAskAgain = root->awar_int(awar_name_neverAskAgain, 0, AW_ROOT_DEFAULT);
112            have_auto_answer            = awar_neverAskAgain->read_int();
113        }
114    }
115
116    if (have_auto_answer>0) {
117        aw_message_cb_result = have_auto_answer-1;
118    }
119    else {
120        char *button_list = strdup(buttons ? buttons : "OK");
121        if (button_list[0] == 0) {
122            freedup(button_list, "Maybe ok,EXIT");
123            GBK_dump_backtrace(stderr, "Empty buttonlist");
124            question = GBS_global_string_copy("%s\n"
125                                              "(Program error - Unsure what happens when you click ok\n"
126                                              " Check console for backtrace and report error)",
127                                              question);
128        }
129
130        AW_awar *awar_quest     = root->awar_string(AWAR_QUESTION);
131        if (!question) question = "<oops - no question?!>";
132        awar_quest->write_string(question);
133
134        size_t question_length, question_lines;
135        aw_detect_text_size(question, question_length, question_lines);
136
137        // hash key to find matching window
138        char *hindex = GBS_global_string_copy("%s$%s$%zu$%zu$%i$%s",
139                                              button_list, uniqueID ? uniqueID : "<NOID>",
140                                              question_length, question_lines, int(fixedSizeButtons),
141                                              helpfile ? helpfile : "");
142
143        static GB_HASH    *hash_windows = 0;
144        if (!hash_windows) hash_windows = GBS_create_hash(256, GB_MIND_CASE);
145        AW_window_message *aw_msg       = (AW_window_message *)GBS_read_hash(hash_windows, hindex);
146
147#if defined(DEBUG)
148        printf("hindex='%s'\n", hindex);
149#endif // DEBUG
150
151        if (!aw_msg) {
152            aw_msg = new AW_window_message;
153            GBS_write_hash(hash_windows, hindex, (long)aw_msg);
154
155            aw_msg->init(root, "QUESTION BOX", false);
156            aw_msg->recalc_size_atShow(AW_RESIZE_DEFAULT); // force size recalc (ignores user size)
157
158            aw_msg->label_length(10);
159
160            aw_msg->at(10, 10);
161            aw_msg->auto_space(10, 10);
162
163            aw_msg->button_length(question_length+3);
164            aw_msg->button_height(question_lines+1);
165
166            aw_msg->create_button(0, AWAR_QUESTION);
167
168            aw_msg->button_height(0);
169
170            aw_msg->at_newline();
171
172            if (fixedSizeButtons) {
173                size_t  max_button_length = helpfile ? 4 : 0;
174                char   *pos               = button_list;
175
176                while (1) {
177                    char *comma       = strchr(pos, ',');
178                    if (!comma) comma = strchr(pos, 0);
179
180                    size_t len                                   = comma-pos;
181                    if (len>max_button_length) max_button_length = len;
182
183                    if (!comma[0]) break;
184                    pos = comma+1;
185                }
186
187                aw_msg->button_length(max_button_length+2);
188            }
189            else {
190                aw_msg->button_length(0);
191            }
192
193            // insert the buttons:
194            char *ret              = strtok(button_list, ",");
195            bool  help_button_done = false;
196            int   counter          = 0;
197
198            while (ret) {
199                if (ret[0] == '^') {
200                    if (helpfile && !help_button_done) {
201                        aw_msg->callback(AW_POPUP_HELP, (AW_CL)helpfile);
202                        aw_msg->create_button("HELP", "HELP", "H");
203                        help_button_done = true;
204                    }
205                    aw_msg->at_newline();
206                    ++ret;
207                }
208                if (strcmp(ret, "EXIT") == 0) {
209                    aw_msg->callback(message_cb, -1);
210                }
211                else {
212                    aw_msg->callback(message_cb, (AW_CL)counter++);
213                }
214
215                if (fixedSizeButtons) {
216                    aw_msg->create_button(0, ret);
217                }
218                else {
219                    aw_msg->create_autosize_button(0, ret);
220                }
221                ret = strtok(NULL, ",");
222            }
223
224            if (helpfile && !help_button_done) { // if not done above
225                aw_msg->callback(AW_POPUP_HELP, (AW_CL)helpfile);
226                aw_msg->create_button("HELP", "HELP", "H");
227                help_button_done = true;
228            }
229
230            if (uniqueID) {
231                aw_msg->at_newline();
232                const char *label = counter>1 ? "Never ask again" : "Never notify me again";
233                aw_msg->label_length(strlen(label));
234                aw_msg->label(label);
235                aw_msg->create_toggle(awar_name_neverAskAgain);
236            }
237
238            aw_msg->window_fit();
239        }
240        else {
241#if defined(DEBUG)
242            printf("[Reusing existing aw_question-window]\n");
243#endif
244        }
245        free(hindex);
246        aw_msg->show_modal();
247
248        free(button_list);
249        aw_message_cb_result = -13;
250
251#if defined(TRACE_STATUS_MORE)
252        fprintf(stderr, "add aw_message_timer_listen_event with delay = %i\n", AW_MESSAGE_LISTEN_DELAY); fflush(stdout);
253#endif // TRACE_STATUS_MORE
254        root->add_timed_callback_never_disabled(AW_MESSAGE_LISTEN_DELAY, aw_message_timer_listen_event, (AW_CL)aw_msg, 0);
255
256        {
257            LocallyModify<bool> flag(root->disable_callbacks, true);
258            while (aw_message_cb_result == -13) {
259                root->process_events();
260            }
261        }
262        aw_msg->hide();
263
264        if (awar_name_neverAskAgain) {
265            AW_awar *awar_neverAskAgain = root->awar(awar_name_neverAskAgain);
266
267            if (awar_neverAskAgain->read_int()) { // user checked "Never ask again"
268                int givenAnswer = aw_message_cb_result >= 0 ? aw_message_cb_result+1 : 0;
269                awar_neverAskAgain->write_int(givenAnswer); // store given answer for "never asking again"
270
271                if (givenAnswer && strchr(buttons, ',') != 0) {
272                    const char *appname = root->program_name;
273                    char       *advice  = GBS_global_string_copy("You will not be asked that question again in this session.\n"
274                                                                 "%s will always assume the answer you just gave.\n"
275                                                                 "\n"
276                                                                 "When you restart %s that question will be asked again.\n"
277                                                                 "To disable that question permanently for future sessions,\n"
278                                                                 "you need to save properties.\n"
279                                                                 "\n"
280                                                                 "Depending on the type of question doing that might be\n"
281                                                                 "helpful or obstructive.\n"
282                                                                 "Disabled questions can be reactivated from the properties menu.\n",
283                                                                 appname, appname);
284                    AW_advice(advice, AW_ADVICE_TOGGLE, "Disabling questions", NULL);
285                    free(advice);
286                }
287            }
288        }
289    }
290
291    free(awar_name_neverAskAgain);
292
293    switch (aw_message_cb_result) {
294        case -1:                // exit with core
295            fprintf(stderr, "Core dump requested\n");
296            ARB_SIGSEGV(1);
297            break;
298        case -2:                // exit without core
299            exit(-1);
300            break;
301    }
302    return aw_message_cb_result;
303}
304
305bool aw_ask_sure(const char *uniqueID, const char *msg) {
306    return aw_question(uniqueID, msg, "Yes,No", true, NULL) == 0;
307}
308void aw_popup_ok(const char *msg) {
309    aw_question(NULL, msg, "Ok", true, NULL);
310}
311void aw_popup_exit(const char *msg) {
312    aw_question(NULL, msg, "EXIT", true, NULL);
313    aw_assert(0); // should not be reached
314    exit(EXIT_FAILURE);
315}
316
317
318// -----------------
319//      aw_input
320
321static char *aw_input_cb_result        = 0;
322static int   aw_string_selected_button = -2;
323
324int aw_string_selection_button() {
325    aw_assert(aw_string_selected_button != -2);
326    return aw_string_selected_button;
327}
328
329#define AW_INPUT_AWAR       "tmp/input/string"
330#define AW_INPUT_TITLE_AWAR "tmp/input/title"
331
332#define AW_FILE_SELECT_BASE        "tmp/file_select"
333#define AW_FILE_SELECT_DIR_AWAR    AW_FILE_SELECT_BASE "/directory"
334#define AW_FILE_SELECT_FILE_AWAR   AW_FILE_SELECT_BASE "/file_name"
335#define AW_FILE_SELECT_FILTER_AWAR AW_FILE_SELECT_BASE "/filter"
336#define AW_FILE_SELECT_TITLE_AWAR  AW_FILE_SELECT_BASE "/title"
337
338static void create_input_awars(AW_root *aw_root) {
339    aw_root->awar_string(AW_INPUT_TITLE_AWAR, "", AW_ROOT_DEFAULT);
340    aw_root->awar_string(AW_INPUT_AWAR,       "", AW_ROOT_DEFAULT);
341}
342
343static void create_fileSelection_awars(AW_root *aw_root) {
344    aw_root->awar_string(AW_FILE_SELECT_TITLE_AWAR, "", AW_ROOT_DEFAULT);
345    aw_root->awar_string(AW_FILE_SELECT_DIR_AWAR, "", AW_ROOT_DEFAULT);
346    aw_root->awar_string(AW_FILE_SELECT_FILE_AWAR, "", AW_ROOT_DEFAULT);
347    aw_root->awar_string(AW_FILE_SELECT_FILTER_AWAR, "", AW_ROOT_DEFAULT);
348}
349
350
351// -------------------------
352//      aw_input history
353
354static deque<string> input_history; // front contains newest entries
355
356#if defined(DEBUG)
357// # define TRACE_HISTORY
358#endif // DEBUG
359
360
361#if defined(TRACE_HISTORY)
362static void dumpHistory(const char *where) {
363    printf("History [%s]:\n", where);
364    for (deque<string>::iterator h = input_history.begin(); h != input_history.end(); ++h) {
365        printf("'%s'\n", h->c_str());
366    }
367}
368#endif // TRACE_HISTORY
369
370static void input_history_insert(const char *str, bool front) {
371    string s(str);
372
373    if (input_history.empty()) {
374        input_history.push_front(""); // insert an empty string into history
375    }
376    else {
377        deque<string>::iterator found = find(input_history.begin(), input_history.end(), s);
378        if (found != input_history.end()) {
379            input_history.erase(found);
380        }
381    }
382    if (front) {
383        input_history.push_front(s);
384    }
385    else {
386        input_history.push_back(s);
387    }
388
389#if defined(TRACE_HISTORY)
390    dumpHistory(GBS_global_string("input_history_insert('%s', front=%i)", str, front));
391#endif // TRACE_HISTORY
392}
393
394void input_history_cb(AW_window *aw, AW_CL cl_mode) {
395    int      mode    = (int)cl_mode;                // -1 = '<' +1 = '>'
396    AW_root *aw_root = aw->get_root();
397    AW_awar *awar    = aw_root->awar(AW_INPUT_AWAR);
398    char    *content = awar->read_string();
399
400    if (content) input_history_insert(content, mode == 1);
401
402    if (!input_history.empty()) {
403        if (mode == -1) {
404            string s = input_history.front();
405            awar->write_string(s.c_str());
406            input_history.pop_front();
407            input_history.push_back(s);
408        }
409        else {
410            string s = input_history.back();
411            awar->write_string(s.c_str());
412            input_history.pop_back();
413            input_history.push_front(s);
414        }
415    }
416
417#if defined(TRACE_HISTORY)
418    dumpHistory(GBS_global_string("input_history_cb(mode=%i)", mode));
419#endif // TRACE_HISTORY
420
421    free(content);
422}
423
424void input_cb(AW_window *aw, AW_CL cd1) {
425    // any previous contents were passed to client (who is responsible to free the resources)
426    // so DON'T free aw_input_cb_result here:
427    aw_input_cb_result        = 0;
428    aw_string_selected_button = int(cd1);
429
430    if (cd1 >= 0) {              // <0 = cancel button -> no result
431        // create heap-copy of result -> client will get the owner
432        aw_input_cb_result = aw->get_root()->awar(AW_INPUT_AWAR)->read_as_string();
433    }
434}
435
436void file_selection_cb(AW_window *aw, AW_CL cd1) {
437    // any previous contents were passed to client (who is responsible to free the resources)
438    // so DON'T free aw_input_cb_result here:
439    aw_input_cb_result        = 0;
440    aw_string_selected_button = int(cd1);
441
442    if (cd1 >= 0) {              // <0 = cancel button -> no result
443        // create heap-copy of result -> client will get the owner
444        aw_input_cb_result = aw->get_root()->awar(AW_FILE_SELECT_FILE_AWAR)->read_as_string();
445    }
446}
447
448#define INPUT_SIZE 50           // size of input prompts in aw_input and aw_string_selection
449
450static AW_window_message *new_input_window(AW_root *root, const char *title, const char *buttons) {
451    // helper for aw_input and aw_string_selection
452    //
453    // 'buttons' comma separated list of button names (buttons starting with \n force a newline)
454
455    AW_window_message *aw_msg = new AW_window_message;
456
457    aw_msg->init(root, title, false);
458
459    aw_msg->label_length(0);
460    aw_msg->auto_space(10, 10);
461
462    aw_msg->at(10, 10);
463    aw_msg->button_length(INPUT_SIZE+1);
464    aw_msg->create_button(0, AW_INPUT_TITLE_AWAR);
465
466    aw_msg->at_newline();
467    aw_msg->create_input_field(AW_INPUT_AWAR, INPUT_SIZE);
468
469    size_t        butCount = 2;                     // ok and cancel
470    ConstStrArray button_names;
471    int           maxlen   = 6;                     // use as min.length for buttons (for 'CANCEL')
472
473    if (buttons) {
474        GBT_split_string(button_names, buttons, ',');
475        butCount = button_names.size();
476
477        for (size_t b = 0; b<butCount; b++) {
478            int len = strlen(button_names[b]);
479            if (len>maxlen) maxlen = len;
480        }
481
482    }
483
484    aw_msg->button_length(maxlen+1);
485
486#define MAXBUTTONSPERLINE 5
487
488    aw_msg->at_newline();
489    aw_msg->callback(input_history_cb, -1); aw_msg->create_button("bwd", "<<", 0);
490    aw_msg->callback(input_history_cb,  1); aw_msg->create_button("fwd", ">>", 0);
491    size_t thisLine = 2;
492
493    // @@@ add a history button (opening a window with elements from history)
494
495    if (butCount>(MAXBUTTONSPERLINE-thisLine) && butCount <= MAXBUTTONSPERLINE) { // approx. 5 buttons (2+3) fit into one line
496        aw_msg->at_newline();
497        thisLine = 0;
498    }
499
500    if (buttons) {
501        for (size_t b = 0; b<butCount; b++) {
502            const char *name    = button_names[b];
503            bool        forceLF = name[0] == '\n';
504
505            if (thisLine >= MAXBUTTONSPERLINE || forceLF) {
506                aw_msg->at_newline();
507                thisLine = 0;
508                if (forceLF) name++;
509            }
510            aw_msg->callback(input_cb, b);          // use b == 0 as result for 1st button, 1 for 2nd button, etc.
511            aw_msg->create_button(name, name, "");
512            thisLine++;
513        }
514    }
515    else {
516        aw_msg->callback(input_cb,  0); aw_msg->create_button("OK", "OK", "O");
517        aw_msg->callback(input_cb, -1); aw_msg->create_button("CANCEL", "CANCEL", "C");
518    }
519
520    return aw_msg;
521}
522
523char *aw_input(const char *title, const char *prompt, const char *default_input) {
524    // prompt user to enter a string
525    //
526    // title         = title of window
527    // prompt        = question
528    // default_input = default for answer (NULL -> "")
529    //
530    // result is NULL, if cancel was pressed
531    // otherwise result contains the user input (maybe an empty string)
532
533    static AW_window_message *aw_msg = 0;
534
535    AW_root *root = AW_root::SINGLETON;
536    if (!aw_msg) create_input_awars(root); // first call -> create awars
537
538    root->awar(AW_INPUT_TITLE_AWAR)->write_string(prompt);
539    aw_assert(strlen(prompt) <= INPUT_SIZE);
540
541    AW_awar *inAwar = root->awar(AW_INPUT_AWAR);
542    if (default_input) {
543        input_history_insert(default_input, true); // insert default into history
544        inAwar->write_string(default_input);
545    }
546    else {
547        inAwar->write_string("");
548    }
549
550    aw_assert(GB_get_transaction_level(inAwar->gb_var) <= 0); // otherwise history would not work
551
552    if (!aw_msg) aw_msg = new_input_window(root, title, NULL);
553    else aw_msg->set_window_title(title);
554
555    aw_msg->window_fit();
556    aw_msg->show_modal();
557    char dummy[]       = "";
558    aw_input_cb_result = dummy;
559
560    root->add_timed_callback_never_disabled(AW_MESSAGE_LISTEN_DELAY, aw_message_timer_listen_event, (AW_CL)aw_msg, 0);
561    {
562        LocallyModify<bool> flag(root->disable_callbacks, true);
563        while (aw_input_cb_result == dummy) {
564            root->process_events();
565        }
566    }
567    aw_msg->hide();
568
569    if (aw_input_cb_result) input_history_insert(aw_input_cb_result, true);
570    return aw_input_cb_result;
571}
572
573char *aw_input(const char *prompt, const char *default_input) {
574    return aw_input("Enter string", prompt, default_input);
575}
576
577static char *aw_input2awar(const char *title, const char *prompt, const char *awar_name) {
578    AW_root *aw_root       = AW_root::SINGLETON;
579    AW_awar *awar          = aw_root->awar(awar_name);
580    char    *default_value = awar->read_string();
581    char    *result        = aw_input(title, prompt, default_value);
582
583    awar->write_string(result);
584    free(default_value);
585
586    return result;
587}
588
589char *aw_input2awar(const char *prompt, const char *awar_name) {
590    return aw_input2awar("Enter string", prompt, awar_name);
591}
592
593
594char *aw_string_selection(const char *title, const char *prompt, const char *default_input, const char *value_list, const char *buttons, char *(*check_fun)(const char*)) {
595    // A modal input window. A String may be entered by hand or selected from value_list
596    //
597    //      title           window title
598    //      prompt          prompt at input field
599    //      default_input   default value (if NULL => "").
600    //      value_list      Existing selections (separated by ';') or NULL if no selection exists
601    //      buttons         String containing answer button names separated by ',' (default is "OK,Cancel")
602    //                      Use aw_string_selected_button() to detect which has been pressed.
603    //      check_fun       function to correct input (or NULL for no check). The function may return NULL to indicate no correction
604    //
605    // returns the value of the inputfield
606
607    static GB_HASH *str_sels = 0; // for each 'buttons' store window + selection list
608
609    if (!str_sels) str_sels = GBS_create_hash(100, GB_MIND_CASE);
610
611    struct str_sel_data {
612        AW_window_message *aw_msg;
613        AW_selection_list *sel;
614    };
615
616    const char   *bkey = buttons ? buttons : ",default,";
617    str_sel_data *sd      = (str_sel_data*)GBS_read_hash(str_sels, bkey);
618    if (!sd) {
619        sd         = new str_sel_data;
620        sd->aw_msg = 0;
621        sd->sel    = 0;
622
623        GBS_write_hash(str_sels, bkey, (long)sd);
624    }
625
626    AW_window_message *& aw_msg = sd->aw_msg;
627    AW_selection_list *& sel    = sd->sel;
628
629    AW_root *root = AW_root::SINGLETON;
630    if (!aw_msg) create_input_awars(root); // first call -> create awars
631
632    root->awar(AW_INPUT_TITLE_AWAR)->write_string(prompt);
633    aw_assert(strlen(prompt) <= INPUT_SIZE);
634
635    AW_awar *inAwar = root->awar(AW_INPUT_AWAR);
636    if (default_input) {
637        input_history_insert(default_input, true); // insert default into history
638        inAwar->write_string(default_input);
639    }
640    else {
641        inAwar->write_string("");
642    }
643
644    aw_assert(GB_get_transaction_level(inAwar->gb_var) <= 0); // otherwise history would not work
645
646    if (!aw_msg) {
647        aw_msg = new_input_window(root, title, buttons);
648
649        aw_msg->at_newline();
650        sel = aw_msg->create_selection_list(AW_INPUT_AWAR, INPUT_SIZE, 10);
651        sel->insert_default("", "");
652        sel->update();
653    }
654    else {
655        aw_msg->set_window_title(title);
656    }
657    aw_msg->window_fit();
658
659    // update the selection box :
660    aw_assert(sel);
661    sel->clear();
662    if (value_list) {
663        char *values = strdup(value_list);
664        char *word;
665
666        for (word = strtok(values, ";"); word; word = strtok(0, ";")) {
667            sel->insert(word, word);
668        }
669        free(values);
670    }
671    sel->insert_default("<new>", "");
672    sel->update();
673
674    // do modal loop :
675    aw_msg->show_modal();
676    char dummy[] = "";
677    aw_input_cb_result = dummy;
678
679    root->add_timed_callback_never_disabled(AW_MESSAGE_LISTEN_DELAY, aw_message_timer_listen_event, (AW_CL)aw_msg, 0);
680    {
681        LocallyModify<bool> flag(root->disable_callbacks, true);
682
683        char *last_input = root->awar(AW_INPUT_AWAR)->read_string();
684        while (aw_input_cb_result == dummy) {
685            root->process_events();
686
687            char *this_input = root->awar(AW_INPUT_AWAR)->read_string();
688            if (strcmp(this_input, last_input) != 0) {
689                if (check_fun) {
690                    char *corrected_input = check_fun(this_input);
691                    if (corrected_input) {
692                        if (strcmp(corrected_input, this_input) != 0) {
693                            root->awar(AW_INPUT_AWAR)->write_string(corrected_input);
694                        }
695                        free(corrected_input);
696                    }
697                }
698                reassign(last_input, this_input);
699            }
700            free(this_input);
701
702            if (!aw_msg->is_shown()) { // somebody hided/closed the window
703                input_cb(aw_msg, (AW_CL)-1); // CANCEL
704                break;
705            }
706        }
707
708        free(last_input);
709    }
710    aw_msg->hide();
711
712    return aw_input_cb_result;
713}
714
715char *aw_string_selection2awar(const char *title, const char *prompt, const char *awar_name, const char *value_list, const char *buttons, char *(*check_fun)(const char*)) {
716    // params see aw_string_selection
717    // default_value is taken from and result is written back to awar 'awar_name'
718
719    AW_root *aw_root       = AW_root::SINGLETON;
720    AW_awar *awar          = aw_root->awar(awar_name);
721    char    *default_value = awar->read_string();
722    char    *result        = aw_string_selection(title, prompt, default_value, value_list, buttons, check_fun);
723
724    awar->write_string(result);
725    free(default_value);
726
727    return result;
728}
729
730// --------------------------
731//      aw_file_selection
732
733char *aw_file_selection(const char *title, const char *dir, const char *def_name, const char *suffix) {
734    AW_root *root = AW_root::SINGLETON;
735
736    static AW_window_simple *aw_msg = 0;
737    if (!aw_msg) create_fileSelection_awars(root);
738
739    {
740        char *edir      = GBS_eval_env(dir);
741        char *edef_name = GBS_eval_env(def_name);
742
743        root->awar(AW_FILE_SELECT_TITLE_AWAR) ->write_string(title);
744        root->awar(AW_FILE_SELECT_DIR_AWAR)   ->write_string(edir);
745        root->awar(AW_FILE_SELECT_FILE_AWAR)  ->write_string(edef_name);
746        root->awar(AW_FILE_SELECT_FILTER_AWAR)->write_string(suffix);
747
748        free(edef_name);
749        free(edir);
750    }
751
752    if (!aw_msg) {
753        aw_msg = new AW_window_simple;
754
755        aw_msg->init(root, "AW_FILE_SELECTION", "File selection");
756        aw_msg->allow_delete_window(false); // disable closing the window
757
758        aw_msg->load_xfig("fileselect.fig");
759
760        aw_msg->at("title");
761        aw_msg->create_button(0, AW_FILE_SELECT_TITLE_AWAR);
762
763        AW_create_fileselection(aw_msg, AW_FILE_SELECT_BASE);
764
765        aw_msg->button_length(7);
766
767        aw_msg->at("ok");
768        aw_msg->callback(file_selection_cb, 0);
769        aw_msg->create_button("OK", "OK", "O");
770
771        aw_msg->at("cancel");
772        aw_msg->callback(file_selection_cb, -1);
773        aw_msg->create_button("CANCEL", "CANCEL", "C");
774
775        aw_msg->window_fit();
776    }
777
778    aw_msg->show_modal();
779    char dummy[] = "";
780    aw_input_cb_result = dummy;
781
782    root->add_timed_callback_never_disabled(AW_MESSAGE_LISTEN_DELAY, aw_message_timer_listen_event, (AW_CL)aw_msg, 0);
783    {
784        LocallyModify<bool> flag(root->disable_callbacks, true);
785        while (aw_input_cb_result == dummy) {
786            root->process_events();
787        }
788    }
789    aw_msg->hide();
790
791    return aw_input_cb_result;
792}
793
794
Note: See TracBrowser for help on using the repository browser.