source: tags/ms_r16q3/WINDOW/AW_select.cxx

Last change on this file was 15176, checked in by westram, 8 years ago
File size: 24.5 KB
Line 
1// ================================================================ //
2//                                                                  //
3//   File      : AW_select.cxx                                      //
4//   Purpose   :                                                    //
5//                                                                  //
6//   Coded by Ralf Westram (coder@reallysoft.de) in February 2010   //
7//   Institute of Microbiology (Technical University Munich)        //
8//   http://www.arb-home.de/                                        //
9//                                                                  //
10// ================================================================ //
11
12#include "aw_select.hxx"
13#include "aw_window_Xm.hxx"
14#include "aw_root.hxx"
15#include "aw_awar.hxx"
16
17#include <arb_strarray.h>
18#include <arb_strbuf.h>
19#include <arb_str.h>
20#include <arb_sort.h>
21#include <ad_cb.h>
22
23#include <Xm/List.h>
24
25__ATTR__NORETURN inline void selection_type_mismatch(const char *triedType) { type_mismatch(triedType, "selection-list"); }
26
27// --------------------------
28//      AW_selection_list
29
30
31AW_selection_list::AW_selection_list(const char *variable_name_, int variable_type_, Widget select_list_widget_)
32    : variable_name(nulldup(variable_name_)),
33      variable_type(AW_VARIABLE_TYPE(variable_type_)),
34      update_cb(NULL),
35      cl_update(0),
36      select_list_widget(select_list_widget_),
37      list_table(NULL),
38      last_of_list_table(NULL),
39      default_select(NULL),
40      next(NULL)
41{}
42
43AW_selection_list::~AW_selection_list() {
44    clear();
45    free(variable_name);
46}
47
48inline XmString XmStringCreateSimple_wrapper(const char *text) {
49    return XmStringCreateSimple((char*)text);
50}
51
52void AW_selection_list::update() {
53    // Warning:
54    // update() will not set the connected awar to the default value
55    // if it contains a value which is not associated with a list entry!
56
57    size_t count = size();
58    if (default_select) count++;
59
60    XmString *strtab = new XmString[count];
61
62    count = 0;
63    for (AW_selection_list_entry *lt = list_table; lt; lt = lt->next) {
64        const char *s2 = lt->get_displayed();
65        if (!s2[0]) s2 = "  ";
66        strtab[count]  = XmStringCreateSimple_wrapper(s2);
67        count++;
68    }
69
70    if (default_select) {
71        const char *s2 = default_select->get_displayed();
72        if (!strlen(s2)) s2 = "  ";
73        strtab[count] = XmStringCreateSimple_wrapper(s2);
74        count++;
75    }
76    if (!count) {
77        strtab[count] = XmStringCreateSimple_wrapper("   ");
78        count ++;
79    }
80
81    XtVaSetValues(select_list_widget, XmNitemCount, count, XmNitems, strtab, NULL);
82
83    refresh();
84
85    for (size_t i=0; i<count; i++) XmStringFree(strtab[i]);
86    delete [] strtab;
87
88    if (update_cb) update_cb(this, cl_update);
89}
90
91void AW_selection_list::set_update_callback(sellist_update_cb ucb, AW_CL cl_user) {
92    aw_assert(!update_cb || !ucb); // overwrite allowed only with NULL!
93
94    update_cb = ucb;
95    cl_update = cl_user;
96}
97
98void AW_selection_list::refresh() {
99    if (!variable_name) return;     // not connected to awar
100
101    AW_root *root  = AW_root::SINGLETON;
102    bool     found = false;
103    int      pos   = 0;
104    AW_awar *awar  = root->awar(variable_name);
105
106    AW_selection_list_entry *lt;
107
108    switch (variable_type) {
109        case AW_STRING: {
110            char *var_value = awar->read_string();
111            for (lt = list_table; lt; lt = lt->next) {
112                if (strcmp(var_value, lt->value.get_string()) == 0) {
113                    found = true;
114                    break;
115                }
116                pos++;
117            }
118            free(var_value);
119            break;
120        }
121        case AW_INT: {
122            int var_value = awar->read_int();
123            for (lt = list_table; lt; lt = lt->next) {
124                if (var_value == lt->value.get_int()) {
125                    found = true;
126                    break;
127                }
128                pos++;
129            }
130            break;
131        }
132        case AW_FLOAT: {
133            float var_value = awar->read_float();
134            for (lt = list_table; lt; lt = lt->next) {
135                if (var_value == lt->value.get_float()) {
136                    found = true;
137                    break;
138                }
139                pos++;
140            }
141            break;
142        }
143        case AW_POINTER: {
144            GBDATA *var_value = awar->read_pointer();
145            for (lt = list_table; lt; lt = lt->next) {
146                if (var_value == lt->value.get_pointer()) {
147                    found = true;
148                    break;
149                }
150                pos++;
151            }
152            break;
153        }
154        default:
155            aw_assert(0);
156            GB_warning("Unknown AWAR type");
157            break;
158    }
159
160    if (found || default_select) {
161        pos++;
162        int top;
163        int vis;
164        XtVaGetValues(select_list_widget,
165                      XmNvisibleItemCount, &vis,
166                      XmNtopItemPosition, &top,
167                      NULL);
168        XmListSelectPos(select_list_widget, pos, False);
169
170        if (pos < top) {
171            if (pos > 1) pos --;
172            XmListSetPos(select_list_widget, pos);
173        }
174        if (pos >= top + vis) {
175            XmListSetBottomPos(select_list_widget, pos + 1);
176        }
177    }
178    else {
179        GBK_terminatef("Selection list '%s' has no default selection", variable_name);
180    }
181}
182
183void AW_selection::refresh() {
184    get_sellist()->clear();
185    fill();
186    get_sellist()->update();
187}
188
189void AW_selection_list::clear() {
190    /** Remove all items from the list. Default item is removed as well.*/
191    while (list_table) {
192        AW_selection_list_entry *nextEntry = list_table->next;
193        delete list_table;
194        list_table = nextEntry;
195    }
196    list_table         = NULL;
197    last_of_list_table = NULL;
198
199    delete_default();
200}
201
202bool AW_selection_list::default_is_selected() const {
203    const char *sel = get_selected_value();
204    if (!sel) {
205        // (case should be impossible in gtk port)
206        return true; // handle "nothing" like default
207    }
208
209    const char *def = get_default_value();
210    return def && (strcmp(sel, def) == 0);
211}
212
213const char *AW_selection_list::get_selected_value() const {
214    int                      i;
215    AW_selection_list_entry *lt;
216    AW_selection_list_entry *found = 0;
217
218    aw_assert(select_list_widget);
219   
220    for (i=1, lt = list_table; lt; i++, lt = lt->next) {
221        lt->is_selected = XmListPosSelected(select_list_widget, i);
222        if (lt->is_selected && !found) found = lt;
223    }
224
225    if (default_select) {
226        default_select->is_selected = XmListPosSelected(select_list_widget, i);
227        if (default_select->is_selected && !found) found = default_select;
228    }
229    return found ? found->value.get_string() : NULL;
230}
231
232AW_selection_list_entry *AW_selection_list::get_entry_at(int index) const {
233    AW_selection_list_entry *entry = list_table;
234    while (index && entry) {
235        entry = entry->next;
236        index--;
237    }
238    return entry;
239}
240
241
242void AW_selection_list::select_default() {
243    set_awar_value(get_default_value());
244}
245
246void AW_selection_list::delete_element_at(const int index) {
247    if (index<0) return;
248
249    AW_selection_list_entry *prev = NULL;
250    if (index>0) {
251        prev = get_entry_at(index-1);
252        if (!prev) return; // invalid index
253    }
254
255    int selected_index = get_index_of_selected();
256    if (index == selected_index) select_default();
257
258    AW_selection_list_entry *toDel = prev ? prev->next : list_table;
259    aw_assert(toDel != default_select);
260
261    (prev ? prev->next : list_table) = toDel->next;
262    delete toDel;
263
264    if (last_of_list_table == toDel) last_of_list_table = prev;
265}
266
267void AW_selection_list::delete_value(const char *value) {
268    int index = get_index_of(value);
269    delete_element_at(index);
270}
271
272const char *AW_selection_list::get_awar_value() const {
273    AW_awar *awar = AW_root::SINGLETON->awar(variable_name);
274    return awar->read_char_pntr();
275}
276
277char *AW_selection_list::get_content_as_string(long number_of_lines) {
278    // number_of_lines == 0 -> print all
279
280    AW_selection_list_entry *lt;
281    GBS_strstruct *fd = GBS_stropen(10000);
282
283    for (lt = list_table; lt; lt = lt->next) {
284        number_of_lines--;
285        GBS_strcat(fd, lt->get_displayed());
286        GBS_chrcat(fd, '\n');
287        if (!number_of_lines) break;
288    }
289    return GBS_strclose(fd);
290}
291
292const char *AW_selection_list::get_default_display() const {
293    return default_select ? default_select->get_displayed() : NULL;
294}
295
296const char *AW_selection_list::get_default_value() const {
297    return default_select ? default_select->value.get_string() : NULL;
298}
299
300int AW_selection_list::get_index_of(const char *searched_value) {
301    /*! get index of an entry in the selection list
302     * @return 0..n-1 index of matching element (or -1)
303     */
304    int element_index = 0;
305    for (AW_selection_list_iterator entry(this); entry; ++entry) {
306        if (strcmp(entry.get_value(), searched_value) == 0) return element_index;
307        ++element_index;
308    }
309    return -1;
310}
311
312int AW_selection_list::get_index_of_selected() {
313    // returns index of element (or index of default)
314    const char *awar_value = get_awar_value();
315    return get_index_of(awar_value);
316}
317
318void AW_selection_list::init_from_array(const CharPtrArray& entries, const char *default_displayed, const char *default_value) {
319    // update selection list with contents of NULL-terminated array 'entries'
320    //
321    // 'default_displayed' and 'default_value' are used as default selection.
322    // To position the default selection, add 'default_value' to 'entries' as well.
323    //
324    // awar value will be changed to 'defaultEntry' if it does not match any other entry
325    //
326    // Note: This works only with selection lists bound to AW_STRING awars.
327
328    aw_assert(default_displayed);
329    aw_assert(default_value);
330
331    // use copies (just in case default_* points to a value free'd by clear())
332    char *defaultDispCopy  = strdup(default_displayed);
333    char *defaultValueCopy = strdup(default_value);
334
335    bool defInserted = false;
336
337    clear();
338    for (int i = 0; entries[i]; ++i) {
339        if (!defInserted && strcmp(entries[i], defaultValueCopy) == 0) {
340            insert_default(defaultDispCopy, defaultValueCopy);
341            defInserted = true;
342        }
343        else {
344            insert(entries[i], entries[i]);
345        }
346    }
347    if (!defInserted) insert_default(defaultDispCopy, defaultValueCopy);
348    update();
349
350    const char *selected = get_selected_value();
351    if (selected) set_awar_value(selected);
352
353    free(defaultValueCopy);
354    free(defaultDispCopy);
355}
356
357void AW_selection_list::insert(const char *displayed, const char *value) {
358    if (variable_type != AW_STRING) {
359        selection_type_mismatch("string");
360        return;
361    }
362
363    if (list_table) {
364        last_of_list_table->next = new AW_selection_list_entry(displayed, value);
365        last_of_list_table = last_of_list_table->next;
366        last_of_list_table->next = NULL;
367    }
368    else {
369        last_of_list_table = list_table = new AW_selection_list_entry(displayed, value);
370    }
371}
372
373void AW_selection_list::delete_default() {
374    /** Removes the default entry from the list*/
375    if (default_select) {
376        delete default_select;
377        default_select = NULL;
378    }
379}
380
381void AW_selection_list::insert_default(const char *displayed, const char *value) {
382    if (variable_type != AW_STRING) {
383        selection_type_mismatch("string");
384        return;
385    }
386    if (default_select) delete_default();
387    default_select = new AW_selection_list_entry(displayed, value);
388}
389
390void AW_selection_list::insert(const char *displayed, int32_t value) {
391    if (variable_type != AW_INT) {
392        selection_type_mismatch("int");
393        return;
394    }
395    if (list_table) {
396        last_of_list_table->next = new AW_selection_list_entry(displayed, value);
397        last_of_list_table = last_of_list_table->next;
398        last_of_list_table->next = NULL;
399    }
400    else {
401        last_of_list_table = list_table = new AW_selection_list_entry(displayed, value);
402    }
403}
404
405void AW_selection_list::insert_default(const char *displayed, int32_t value) {
406    if (variable_type != AW_INT) {
407        selection_type_mismatch("int");
408        return;
409    }
410    if (default_select) delete_default();
411    default_select = new AW_selection_list_entry(displayed, value);
412}
413
414
415void AW_selection_list::insert(const char *displayed, GBDATA *pointer) {
416    if (variable_type != AW_POINTER) {
417        selection_type_mismatch("pointer");
418        return;
419    }
420    if (list_table) {
421        last_of_list_table->next = new AW_selection_list_entry(displayed, pointer);
422        last_of_list_table = last_of_list_table->next;
423        last_of_list_table->next = NULL;
424    }
425    else {
426        last_of_list_table = list_table = new AW_selection_list_entry(displayed, pointer);
427    }
428}
429
430void AW_selection_list::insert_default(const char *displayed, GBDATA *pointer) {
431    if (variable_type != AW_POINTER) {
432        selection_type_mismatch("pointer");
433        return;
434    }
435    if (default_select) delete_default();
436    default_select = new AW_selection_list_entry(displayed, pointer);
437}
438
439
440void AW_selection_list::move_content_to(AW_selection_list *target_list) {
441    //! move all entries (despite default entry) to another AW_selection_list
442
443    if (default_select) {
444        char *defDisp = strdup(default_select->get_displayed());
445        char *defVal  = strdup(default_select->value.get_string());
446
447        delete_default();
448        move_content_to(target_list);
449        insert_default(defDisp, defVal);
450
451        free(defVal);
452        free(defDisp);
453    }
454    else {
455        AW_selection_list_entry *entry = list_table;
456        while (entry) {
457            if (!target_list->list_table) {
458                target_list->last_of_list_table = target_list->list_table = new AW_selection_list_entry(entry->get_displayed(), entry->value.get_string());
459            }
460            else {
461                target_list->last_of_list_table->next = new AW_selection_list_entry(entry->get_displayed(), entry->value.get_string());
462                target_list->last_of_list_table = target_list->last_of_list_table->next;
463                target_list->last_of_list_table->next = NULL;
464            }
465            entry = entry->next;
466        }
467        clear();
468    }
469}
470
471void AW_selection_list::move_selection(int offset) {
472    /*! move selection 'offset' position
473     *  offset == 1  -> select next element
474     *  offset == -1 -> select previous element
475     */
476
477    int index = get_index_of_selected();
478    select_element_at(index+offset);
479}
480
481const char *AW_selection_list::get_value_at(int index) {
482    // get value of the entry at position 'index' [0..n-1] of the 'selection_list'
483    // returns NULL if index is out of bounds
484    AW_selection_list_entry *entry = get_entry_at(index);
485    return entry ? entry->value.get_string() : NULL;
486}
487
488void AW_selection_list::select_element_at(int wanted_index) {
489    const char *wanted_value = get_value_at(wanted_index);
490
491    if (!wanted_value) {
492        wanted_value = get_default_value();
493        if (!wanted_value) wanted_value = "";
494    }
495
496    set_awar_value(wanted_value);
497}
498
499void AW_selection_list::set_awar_value(const char *new_value) {
500    AW_awar *awar = AW_root::SINGLETON->awar(variable_name);
501    awar->write_string(new_value);
502}
503
504void AW_selection_list::set_file_suffix(const char *suffix) {
505    AW_root *aw_root = AW_root::SINGLETON;
506    char     filter[200];
507    sprintf(filter, "tmp/save_box_sel_%li/filter", (long)this);
508    aw_root->awar_string(filter, suffix);
509    sprintf(filter, "tmp/load_box_sel_%li/filter", (long)this);
510    aw_root->awar_string(filter, suffix);
511}
512
513size_t AW_selection_list::size() {
514    AW_selection_list_entry *lt    = list_table;
515    size_t                  count = 0;
516
517    while (lt) {
518        ++count;
519        lt = lt->next;
520    }
521    return count;
522}
523
524static int sel_sort_backward(const char *d1, const char *d2) { return strcmp(d2, d1); }
525static int sel_isort_backward(const char *d1, const char *d2) { return ARB_stricmp(d2, d1); }
526static int gb_compare_function__2__sellist_cmp_fun(const void *t1, const void *t2, void *v_selcmp) {
527    sellist_cmp_fun selcmp = (sellist_cmp_fun)v_selcmp;
528    return selcmp(static_cast<const AW_selection_list_entry*>(t1)->get_displayed(),
529                  static_cast<const AW_selection_list_entry*>(t2)->get_displayed());
530}
531
532void AW_selection_list::sortCustom(sellist_cmp_fun cmp) {
533    // WARNING: function behaves different in motif and gtk:
534    // gtk also sorts default-element, motif always places default-element @ bottom
535    size_t count = size();
536    if (count) {
537        AW_selection_list_entry **tables = new AW_selection_list_entry *[count];
538        count = 0;
539        for (AW_selection_list_entry *lt = list_table; lt; lt = lt->next) {
540            tables[count++] = lt;
541        }
542
543        GB_sort((void**)tables, 0, count, gb_compare_function__2__sellist_cmp_fun, (void*)cmp);
544
545        size_t i;
546        for (i=0; i<count-1; i++) {
547            tables[i]->next = tables[i+1];
548        }
549        tables[i]->next = 0;
550        list_table = tables[0];
551        last_of_list_table = tables[i];
552
553        delete [] tables;
554    }
555}
556
557void AW_selection_list::sort(bool backward, bool case_sensitive) {
558    // WARNING: function behaves different in motif and gtk:
559    // gtk also sorts default-element, motif always places default-element @ bottom
560    sellist_cmp_fun cmp;
561    if (backward) {
562        if (case_sensitive) cmp = sel_sort_backward;
563        else cmp                = sel_isort_backward;
564    }
565    else {
566        if (case_sensitive) cmp = strcmp;
567        else cmp                = ARB_stricmp;
568    }
569    sortCustom(cmp);
570}
571
572void AW_selection_list::to_array(StrArray& array, bool values) {
573    /*! read contents of selection list into an array.
574     * @param values true->read values, false->read displayed strings
575     * Use GBT_free_names() to free the result.
576     *
577     * Note: if 'values' is true, this function only works for string selection lists!
578     */
579
580    array.reserve(size());
581
582    for (AW_selection_list_entry *lt = list_table; lt; lt = lt->next) {
583        array.put(strdup(values ? lt->value.get_string() : lt->get_displayed()));
584    }
585    aw_assert(array.size() == size());
586}
587
588GB_HASH *AW_selection_list::to_hash(bool case_sens) {
589    // creates a hash (key = value of selection list, value = display string from selection list)
590    // (Warning: changing the selection list will render the hash invalid!)
591
592    GB_HASH *hash = GBS_create_hash(size(), case_sens ? GB_MIND_CASE : GB_IGNORE_CASE);
593
594    for (AW_selection_list_entry *lt = list_table; lt; lt = lt->next) {
595        GBS_write_hash(hash, lt->value.get_string(), (long)lt->get_displayed());
596    }
597
598    return hash;
599}
600
601char *AW_selection_list_entry::copy_string_for_display(const char *str) {
602    size_t  len     = strlen(str);
603    bool    tooLong = len>MAX_DISPLAY_LENGTH;
604    char   *out;
605    if (tooLong) {
606        out = ARB_strndup(str, MAX_DISPLAY_LENGTH);
607        { // add message about truncation
608            char   *truncated = GBS_global_string_copy(" <truncated - original contains %zu byte>", len);
609            size_t  tlen      = strlen(truncated);
610            aw_assert(MAX_DISPLAY_LENGTH>tlen);
611            memcpy(out+MAX_DISPLAY_LENGTH-tlen, truncated, tlen);
612        }
613        len = MAX_DISPLAY_LENGTH;
614    }
615    else {
616        out = ARB_strduplen(str, len);
617    }
618
619    for (size_t i = 0; i<len; ++i) {
620        switch (out[i]) {
621            case ',':   out[i] = ';'; break;
622            case '\n':  out[i] = '#'; break;
623        }
624    }
625    return out;
626}
627
628// -------------------------
629//      AW_DB_selection
630
631static void AW_DB_selection_refresh_cb(GBDATA *, AW_DB_selection *selection) {
632    selection->refresh();
633}
634
635AW_DB_selection::AW_DB_selection(AW_selection_list *sellist_, GBDATA *gbd_)
636    : AW_selection(sellist_)
637    , gbd(gbd_)
638{
639    GB_transaction ta(gbd);
640    GB_add_callback(gbd, GB_CB_CHANGED, makeDatabaseCallback(AW_DB_selection_refresh_cb, this));
641}
642
643AW_DB_selection::~AW_DB_selection() {
644    GB_transaction ta(gbd);
645    GB_remove_callback(gbd, GB_CB_CHANGED, makeDatabaseCallback(AW_DB_selection_refresh_cb, this));
646}
647
648GBDATA *AW_DB_selection::get_gb_main() {
649    return GB_get_root(gbd);
650}
651
652// --------------------------------------------------------------------------------
653
654#ifdef UNIT_TESTS
655#ifndef TEST_UNIT_H
656#include <test_unit.h>
657#endif
658
659#define TEST_LIST_CONTENT(list,values,expected) do {    \
660        StrArray a;                                     \
661        (list).to_array(a, values);                     \
662        char *str = GBT_join_strings(a, ';');           \
663        TEST_EXPECT_EQUAL(str, expected);               \
664        free(str);                                      \
665    } while(0)
666
667#define TEST_GET_LIST_CONTENT(list,expected) do {       \
668        char *str = (list).get_content_as_string(10);   \
669        TEST_EXPECT_EQUAL(str, expected);               \
670        free(str);                                      \
671    } while(0)
672
673void TEST_selection_list_access() {
674#if defined(ARB_GTK)
675    AW_selection_list list0(NULL, false);
676    AW_selection_list list1(NULL, false);
677    AW_selection_list list2(NULL, false);
678#else // ARB_MOTIF
679    AW_selection_list list0("bla", GB_STRING, NULL);
680    AW_selection_list list1("bla", GB_STRING, NULL);
681    AW_selection_list list2("alb", GB_STRING, NULL);
682#endif
683
684    list0.insert_default("First", "1st");
685    list0.insert("Second", "2nd");
686    list0.insert("Third", "3rd");
687
688    list1.insert("First", "1st");
689    list1.insert_default("Second", "2nd");
690    list1.insert("Third", "3rd");
691
692    list2.insert("First", "1st");
693    list2.insert("Second", "2nd");
694    list2.insert("Third", "3rd");
695    list2.insert_default("Default", "");
696
697    TEST_EXPECT_EQUAL(list0.size(), 2);
698    TEST_EXPECT_EQUAL(list1.size(), 2);
699    TEST_EXPECT_EQUAL(list2.size(), 3);
700
701    TEST_EXPECT_EQUAL(list1.get_default_value(), "2nd");
702    TEST_EXPECT_EQUAL(list1.get_default_display(), "Second");
703
704    TEST_EXPECT_EQUAL(list0.get_index_of("1st"), -1); // default value is not indexed
705    TEST_EXPECT_EQUAL(list0.get_index_of("2nd"), 0);
706    TEST_EXPECT_EQUAL(list0.get_index_of("3rd"), 1);  // = second non-default entry
707
708    TEST_EXPECT_EQUAL(list1.get_index_of("1st"), 0);
709    TEST_EXPECT_EQUAL(list1.get_index_of("2nd"), -1); // default value is not indexed
710    TEST_EXPECT_EQUAL(list1.get_index_of("3rd"), 1);  // = second non-default entry
711
712    TEST_EXPECT_EQUAL(list2.get_index_of("1st"), 0);
713    TEST_EXPECT_EQUAL(list2.get_index_of("2nd"), 1);
714    TEST_EXPECT_EQUAL(list2.get_index_of("3rd"), 2);
715
716
717    TEST_EXPECT_EQUAL(list0.get_value_at(0), "2nd");
718    TEST_EXPECT_EQUAL(list0.get_value_at(1), "3rd");
719    TEST_EXPECT_NULL(list0.get_value_at(2));
720
721    TEST_EXPECT_EQUAL(list1.get_value_at(0), "1st");
722    TEST_EXPECT_EQUAL(list1.get_value_at(1), "3rd");
723    TEST_EXPECT_NULL(list1.get_value_at(2));
724
725    TEST_EXPECT_EQUAL(list2.get_value_at(0), "1st");
726    TEST_EXPECT_EQUAL(list2.get_value_at(1), "2nd");
727    TEST_EXPECT_EQUAL(list2.get_value_at(2), "3rd");
728    TEST_EXPECT_NULL(list2.get_value_at(3));
729
730    TEST_LIST_CONTENT(list1, true,  "1st;3rd");
731    TEST_LIST_CONTENT(list1, false, "First;Third");
732    TEST_GET_LIST_CONTENT(list1,    "First\nThird\n");
733
734    TEST_LIST_CONTENT(list2, true,  "1st;2nd;3rd");
735    TEST_LIST_CONTENT(list2, false, "First;Second;Third");
736    TEST_GET_LIST_CONTENT(list2,    "First\nSecond\nThird\n");
737
738    {
739        AW_selection_list_iterator iter1(&list1);
740        AW_selection_list_iterator iter2(&list2);
741
742        TEST_EXPECT(bool(iter1));
743        TEST_EXPECT(bool(iter2));
744
745        TEST_EXPECT_EQUAL(iter1.get_displayed(), "First");
746        TEST_EXPECT_EQUAL(iter2.get_displayed(), "First");
747
748        TEST_EXPECT_EQUAL(iter1.get_value(), "1st");
749        TEST_EXPECT_EQUAL(iter2.get_value(), "1st");
750
751        ++iter1;
752        ++iter2;
753
754        TEST_EXPECT(bool(iter1));
755        TEST_EXPECT(bool(iter2));
756
757        TEST_EXPECT_EQUAL(iter1.get_displayed(), "Third");
758        TEST_EXPECT_EQUAL(iter2.get_displayed(), "Second");
759
760        TEST_EXPECT_EQUAL(iter1.get_value(), "3rd");
761        TEST_EXPECT_EQUAL(iter2.get_value(), "2nd");
762
763        ++iter1;
764        ++iter2;
765
766        TEST_REJECT(bool(iter1));
767        TEST_EXPECT(bool(iter2));
768    }
769
770    {
771#if defined(ARB_GTK)
772        AW_selection_list copy1(NULL, false);
773        AW_selection_list copy2(NULL, false);
774#else // ARB_MOTIF
775        AW_selection_list copy1("c1", GB_STRING, NULL);
776        AW_selection_list copy2("c2", GB_STRING, NULL);
777#endif
778
779        list1.move_content_to(&copy1);
780        list2.move_content_to(&copy2);
781
782        TEST_EXPECT_EQUAL(list1.size(), 0);
783        TEST_EXPECT_EQUAL(list2.size(), 0);
784
785        TEST_LIST_CONTENT(copy1, true, "1st;3rd");
786        TEST_LIST_CONTENT(copy2, true, "1st;2nd;3rd");
787    }
788}
789TEST_PUBLISH(TEST_selection_list_access);
790
791#endif // UNIT_TESTS
792
793// --------------------------------------------------------------------------------
794
Note: See TracBrowser for help on using the repository browser.