source: tags/ms_r16q2/SECEDIT/SEC_main.cxx

Last change on this file was 14952, checked in by westram, 8 years ago
  • fix canvas resize/zoom-reset
    • replaced calls to AWT_expose_cb by AWT_canvas::refresh
    • replaced calls to AWT_resize_cb by AWT_canvas::zoom_reset_and_refresh
    • fixed double refresh in AWT_canvas::scroll
    • fixed recalc_size(true)
      • if canvas is scrolled out at top or left side ⇒ fix resulting scroll-offset according to size-change
    • instead of zoom_reset do recalc_size when
      • jumping to species in folded group (or outside logical subtree)
      • changing vertical branch distance or group scales (in "Tree Settings")
      • changing font(size)
    • never trigger zoom-reset in AWT_graphic_tree::check_update
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 29.8 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : SEC_main.cxx                                      //
4//   Purpose   : main part of SECEDIT                              //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include "SEC_root.hxx"
12#include "SEC_graphic.hxx"
13#include "SEC_helix.hxx"
14#include "SEC_drawn_pos.hxx"
15#include "SEC_toggle.hxx"
16
17#include <BufferedFileReader.h>
18
19#include <aw_awars.hxx>
20#include <aw_preset.hxx>
21#include <aw_file.hxx>
22#include <aw_msg.hxx>
23#include <aw_root.hxx>
24#include <aw_question.hxx>
25
26#include <mode_text.h>
27
28#include <arb_file.h>
29#include <awt_config_manager.hxx>
30
31#ifndef sec_assert // happens in NDEBUG mode
32#define sec_assert(cond) arb_assert(cond)
33#endif
34
35void SEC_root::invalidate_base_positions() {
36    if (root_loop) {
37        SEC_base_part *start_part = root_loop->get_fixpoint_strand();
38        SEC_base_part *part       = start_part;
39
40        do {
41            part->get_region()->invalidate_base_count();
42            part = part->next();
43        }
44        while (part != start_part);
45    }
46}
47
48// ------------------------------------------------------
49//      auto-scrolling (triggered by structure self)
50
51void SEC_root::nail_position(size_t absPos) {
52    if (drawnPositions) {
53        nailedAbsPos = absPos;
54        drawnAbsPos  = *drawnPositions->drawn_at(absPos);
55    }
56}
57
58void SEC_root::nail_cursor() { // re-position on cursor
59    if (cursorAbsPos >= 0) {
60        if (drawnPositions && !drawnPositions->empty()) {
61            size_t abs;
62            drawnAbsPos  = drawnPositions->drawn_after(cursorAbsPos-1, &abs);
63            nailedAbsPos = abs;
64        }
65    }
66}
67
68void SEC_root::add_autoscroll(const Vector& scroll) {
69    if (autoscroll) *autoscroll += scroll;
70    else autoscroll              = new Vector(scroll);
71}
72
73bool SEC_root::perform_autoscroll() {
74    bool        scrolled = false;
75    AWT_canvas *canvas   = db->canvas();
76
77    if (canvas && (nailedAbsPos != -1 || autoscroll)) {
78        AW_device *device = canvas->aww->get_device(AW_MIDDLE_AREA);
79
80        if (nailedAbsPos != -1) {
81            {
82                int     absPos = nailedAbsPos;
83                Vector *scroll = autoscroll;
84
85                // avoid endless recursion:
86                nailedAbsPos = -1;
87                autoscroll   = 0;
88
89#if defined(WARN_TODO)
90#warning make the refresh invisible
91#endif
92                canvas->refresh();
93
94                nailedAbsPos = absPos;
95                autoscroll   = scroll;
96            }
97            const Position *newPos = drawnPositions->drawn_at(nailedAbsPos);
98            if (newPos) {
99                Vector old2new(drawnAbsPos, *newPos);
100#if defined(DEBUG) && 0
101                printf("drawnAbsPos=%.2f/%.2f newPos=%.2f/%.2f old2new=%.2f/%.2f\n",
102                       drawnAbsPos.xpos(), drawnAbsPos.ypos(),
103                       newPos->xpos(), newPos->ypos(),
104                       old2new.x(), old2new.y());
105#endif // DEBUG
106                add_autoscroll(old2new);
107            }
108            nailedAbsPos = -1;
109        }
110        if (autoscroll) {
111            canvas->init_device(device); // loads correct zoom
112            Vector screen_scroll = device->transform(*autoscroll);
113
114#if defined(DEBUG) && 0
115            printf("autoscroll=%.2f/%.2f screen_scroll=%.2f/%.2f\n",
116                   autoscroll->x(), autoscroll->y(),
117                   screen_scroll.x(), screen_scroll.y());
118#endif // DEBUG
119
120            delete autoscroll;
121            autoscroll = 0;
122
123            device->clear(-1);
124            canvas->scroll(screen_scroll);
125            scrolled = true;
126        }
127    }
128    return scrolled;
129}
130// --------------------------------------------------------------------------------
131
132void SEC_root::position_cursor(bool toCenter, bool evenIfVisible) {
133    // centers the cursor in display (or scrolls it into view)
134    // if 'evenIfVisible' is true, always do it, otherwise only if not (fully) visible
135
136    const LineVector& cursorLine = get_last_drawed_cursor_position();
137    sec_assert(cursorLine.valid());
138
139    AWT_canvas *scr    = db->canvas();
140    AW_device  *device = scr->aww->get_device(AW_MIDDLE_AREA);
141
142    Rectangle cursor(device->transform(cursorLine));
143    Rectangle screen(device->get_area_size(), INCLUSIVE_OUTLINE);
144
145    if (evenIfVisible || !screen.contains(cursor)) {
146        if (!toCenter) {
147            if (perform_autoscroll()) {
148                cursor = Rectangle(device->transform(cursorLine));
149                if (!screen.contains(cursor)) {
150                    toCenter = true;
151                }
152            }
153            else { // if autoscroll didn't work
154                toCenter = true; // center cursor
155            }
156        }
157
158        if (toCenter) {
159            Vector scroll(cursor.centroid(), screen.centroid());
160
161#if defined(DEBUG) && 1
162            printf("Auto-scroll: scroll = (%f, %f) [Center cursor]\n", scroll.x(), scroll.y());
163#endif
164            scr->scroll(-scroll);
165            scr->refresh();
166        }
167    }
168}
169
170static void SEC_toggle_cb(AW_window*, const SEC_db_interface *db) {
171    GB_ERROR error = db->structure()->next();
172    if (error) aw_message(error);
173    db->canvas()->refresh();
174}
175
176static void SEC_center_cb(AW_window *, SEC_root *root) {
177    root->position_cursor(true, true);
178}
179
180static void SEC_fit_window_cb(AW_window*, const SEC_db_interface *db) {
181    db->graphic()->request_update(SEC_UPDATE_ZOOM_RESET);
182    db->canvas()->refresh();
183}
184
185static void sec_mode_event(AW_window *aws, SEC_root *sec_root, AWT_COMMAND_MODE mode) {
186    const char *text = 0;
187    switch (mode) {
188        case AWT_MODE_ZOOM: text = MODE_TEXT_STANDARD_ZOOMMODE(); break;
189
190        case AWT_MODE_EDIT:   text = MODE_TEXT_1BUTTON("CONSTRAINT", "modify constraint");       break;
191        case AWT_MODE_CURSOR: text = MODE_TEXT_1BUTTON("SET CURSOR", "set cursor in ARB_EDIT4"); break;
192
193        case AWT_MODE_FOLD:    text = MODE_TEXT_2BUTTONS("FOLD",       "fold helix",                              "unfold helix");                  break;
194        case AWT_MODE_SETROOT: text = MODE_TEXT_2BUTTONS("SET ROOT",   "set logical center of structure",         "reset angles on sub-structure"); break;
195        case AWT_MODE_ROTATE:  text = MODE_TEXT_2BUTTONS("ROTATE",     "rotate helix/loop",                       "same w/o substructure");         break;
196        case AWT_MODE_STRETCH: text = MODE_TEXT_2BUTTONS("STRETCH",    "click and drag to stretch helices/loops", "reset");                         break;
197        case AWT_MODE_PINFO:   text = MODE_TEXT_2BUTTONS("PROBE INFO", "display PROBE information",               "undisplay");                     break;
198
199        default: text = no_mode_text_defined(); break;
200    }
201
202    sec_root->set_show_constraints((mode == AWT_MODE_STRETCH || mode == AWT_MODE_EDIT)
203                                   ? SEC_ANY_TYPE
204                                   : SEC_NO_TYPE);
205
206    sec_assert(strlen(text) < AWAR_FOOTER_MAX_LEN); // text too long!
207
208    aws->get_root()->awar(AWAR_FOOTER)->write_string(text);
209
210    AWT_canvas *scr = sec_root->get_db()->canvas();
211    scr->set_mode(mode);
212    scr->refresh();
213}
214
215static void SEC_undo_cb(AW_window *, const SEC_db_interface *db, GB_UNDO_TYPE undo_type) {
216    GBDATA   *gb_main = db->gbmain();
217    GB_ERROR  error   = GB_undo(gb_main, undo_type);
218    if (error) {
219        aw_message(error);
220    }
221    else {
222        GB_begin_transaction(gb_main);
223        GB_commit_transaction(gb_main);
224        db->canvas()->refresh();
225    }
226}
227
228// --------------------------------------------------------------------------------
229
230#define ASS       "ARB secondary structure v1" // don't change version here!
231#define ASS_START "[" ASS "]"
232#define ASS_EOS   "[end of structure]"
233#define ASS_EOF   "[end of " ASS "]"
234
235static void export_structure_to_file(AW_window *, const SEC_db_interface *db) {
236    GB_ERROR  error    = 0;
237    SEC_root *sec_root = db->secroot();
238
239    if (!sec_root->get_root_loop()) {
240        error = "Please select a species (to display structure once) before saving";
241    }
242    else {
243        AW_root *aw_root  = db->awroot();
244        char    *filename = aw_root->awar(AWAR_SECEDIT_SAVEDIR"/file_name")->read_string();
245        FILE    *out      = fopen(filename, "wt");
246
247        if (out) {
248
249            fputs(ASS_START, out); fputc('\n', out);
250
251            char *strct = sec_root->buildStructureString();
252            fputs(strct, out);
253            delete [] strct;
254
255            fputs(ASS_EOS, out); fputc('\n', out);
256
257            const XString& xstr     = sec_root->get_xString();
258            const char    *x_string = xstr.get_x_string();
259
260            sec_assert(xstr.get_x_string_length() == strlen(x_string));
261
262            char *foldInfo = SEC_xstring_to_foldedHelixList(x_string, xstr.get_x_string_length(), sec_root->get_helixDef(), error);
263            if (foldInfo) {
264                fprintf(out, "foldedHelices=%s\n", foldInfo);
265                free(foldInfo);
266            }
267
268            fputs(ASS_EOF, out); fputc('\n', out);
269            fclose(out);
270
271            if (error) GB_unlink_or_warn(filename, &error);
272        }
273        else {
274            error = GB_export_errorf("Can't write secondary structure to '%s'", filename);
275        }
276
277        free(filename);
278    }
279    if (error) aw_message(error);
280}
281
282inline GB_ERROR expectedError(const char *expected) {
283    return GBS_global_string("expected '%s'", expected);
284}
285inline GB_ERROR expectContent(LineReader& file, const char *expected) {
286    GB_ERROR error = 0;
287    string   line;
288    if (!file.getLine(line) || line != expected) {
289        error = expectedError(expected);
290    }
291    return error;
292}
293
294static string scanToken(LineReader& file, string& rest, GB_ERROR& error) {
295    string line;
296    string token;
297
298    sec_assert(error == 0);
299
300    if (file.getLine(line)) {
301        size_t equal = line.find('=');
302
303        if (equal == string::npos) {
304            error = "Expected '='";
305        }
306        else {
307            token = line.substr(0, equal);
308            rest  = line.substr(equal+1);
309        }
310    }
311    else {
312        error = "Unexpected EOF";
313    }
314    return token;
315}
316
317static GB_ERROR expectToken(LineReader& file, const char *token, string& content) {
318    GB_ERROR error      = 0;
319    string   foundToken = scanToken(file, content, error);
320    if (foundToken != token) error = expectedError(token);
321    return error;
322}
323
324static void import_structure_from_file(AW_window *, const SEC_db_interface *db) {
325    GB_ERROR  error = 0;
326    SEC_root *root  = db->secroot();
327
328    if (!root->has_xString()) {
329        error = "Please select a species in EDIT4";
330    }
331    else {
332        char        *filename = db->awroot()->awar(AWAR_SECEDIT_SAVEDIR"/file_name")->read_string();
333        FILE        *in       = fopen(filename, "rt"); // closed by FileBuffer
334
335        if (!in) {
336            error = GB_export_errorf("Can't open file '%s'", filename);
337        }
338        else {
339            BufferedFileReader file(filename, in);
340            error = expectContent(file, ASS_START);
341
342            string structure;
343            while (!error) {
344                string line;
345                if (!file.getLine(line)) error = expectedError(ASS_EOS);
346                else {
347                    if (line == ASS_EOS) break;
348                    structure += line + "\n";
349                }
350            }
351
352            char *x_string = 0;
353            if (!error) {
354                string content;
355                string token = scanToken(file, content, error);
356
357                if (!error) {
358                    // we already have an existing xstring, use it's length for new xstring
359                    size_t xlength = root->get_xString().getLength();
360
361                    if (token == "foldedHelices") { // new version
362                        x_string = SEC_foldedHelixList_to_xstring(content.c_str(), xlength, root->get_helixDef(), error); // sets error
363                    }
364                    else if (token == "no of helices") { // old version
365                        int saved_helices = atoi(content.c_str());
366
367                        error             = expectToken(file, "length of xstring", content); // ignore, using curr value
368                        if (!error) error = expectToken(file, "xstring_rel_helix", content);
369                        if (!error) {
370                            int helices_in_db;
371                            x_string = old_decode_xstring_rel_helix(content.c_str(), xlength, root->get_helixDef(), &helices_in_db);
372                            if (helices_in_db != saved_helices) {
373                                error = GBS_global_string("Number of helices does not match (file=%i, db=%i).\n"
374                                                          "Saving the structure again from another DB with correct number of helices will work around this restriction.",
375                                                          saved_helices, helices_in_db);
376                            }
377                        }
378                    }
379                    else {
380                        error = "Expected 'foldedHelices' or 'no of helices'";
381                    }
382                }
383                if (!error) error = expectContent(file, ASS_EOF);
384            }
385
386            if (error) {
387                error = GBS_static_string(file.lineError(error).c_str());
388            }
389            else {
390                db->graphic()->write_data_to_db(structure.c_str(), x_string);
391                db->canvas()->refresh();
392            }
393            free(x_string);
394        }
395        free(filename);
396    }
397    if (error) aw_message(error);
398}
399
400#undef ASS
401#undef ASS_START
402#undef ASS_EOS
403#undef ASS_EOF
404
405static AW_window *SEC_importExport(AW_root *root, bool export_to_file, const SEC_db_interface *db) {
406    AW_window_simple *aws = new AW_window_simple;
407
408    if (export_to_file) aws->init(root, "export_secondary_structure", "Export secondary structure to ...");
409    else                aws->init(root, "import_secondary_structure", "Import secondary structure from ...");
410
411    aws->load_xfig("sec_imexport.fig");
412
413    aws->at("close");
414    aws->callback(AW_POPDOWN);
415    aws->create_button("CLOSE", "CLOSE", "C");
416
417    aws->at("help");
418    aws->callback(makeHelpCallback("sec_imexport.hlp"));
419    aws->create_button("HELP", "HELP", "H");
420
421    AW_create_standard_fileselection(aws, AWAR_SECEDIT_SAVEDIR);
422
423    aws->at("save");
424    if (export_to_file) {
425        aws->callback(makeWindowCallback(export_structure_to_file, db));
426        aws->create_button("EXPORT", "EXPORT", "E");
427    }
428    else {
429        aws->callback(makeWindowCallback(import_structure_from_file, db));
430        aws->create_button("IMPORT", "IMPORT", "I");
431    }
432
433    return aws;
434}
435
436static void SEC_rename_structure(AW_window*, const SEC_db_interface *db) {
437    SEC_structure_toggler *structure = db->structure();
438
439    char *new_name = aw_input("Rename structure", "New name", structure->name());
440    if (new_name) {
441        structure->setName(new_name);
442        free(new_name);
443        db->canvas()->refresh();
444    }
445}
446
447static void SEC_new_structure(AW_window*, const SEC_db_interface *db) {
448    SEC_structure_toggler *structure = db->structure();
449
450    if (!structure) {
451        db->init_toggler();
452        structure = db->structure();
453        sec_assert(structure);
454    }
455
456    GB_ERROR error = 0;
457    bool     done  = false;
458
459    switch (aw_question(NULL, "Create new structure?", "Default bone,Copy current,Abort")) {
460        case 0:                 // default bone
461            error = structure->copyTo("Default");
462            if (!error) {
463                db->secroot()->create_default_bone();
464                db->graphic()->save(NULL, NULL);
465                done = true;
466            }
467            break;
468
469        case 1:                 // copy current
470            error = structure->copyTo(GBS_global_string("%s(copy)", structure->name()));
471            done  = !error;
472            break;
473
474        case 2:                 // abort
475            break;
476    }
477
478    if (done) {
479        db->graphic()->request_update(SEC_UPDATE_ZOOM_RESET);
480        db->canvas()->refresh();
481        SEC_rename_structure(0, db);
482    }
483}
484
485static void SEC_delete_structure(AW_window*, const SEC_db_interface *db) {
486    SEC_structure_toggler *structure = db->structure();
487
488    if (structure->getCount()>1) {
489        if (aw_ask_sure("delete_sec_structure", GBS_global_string("Are you sure to delete structure '%s'?", structure->name()))) {
490            GB_ERROR error = structure->remove();
491            if (error) aw_message(error);
492            db->canvas()->refresh();
493        }
494    }
495    else {
496        aw_message("You cannot delete the last structure");
497    }
498}
499
500enum SyncColors {
501    COLOR_SYNC_SEARCH = 1,
502    COLOR_SYNC_RANGE  = 2,
503    COLOR_SYNC_REST   = 4,
504
505    COLOR_SYNC_ALL = (COLOR_SYNC_SEARCH|COLOR_SYNC_RANGE|COLOR_SYNC_REST),
506};
507
508static void SEC_sync_colors(AW_window *aww, SyncColors which) {
509    // overwrites color settings with those from EDIT4
510
511    if (which & COLOR_SYNC_SEARCH) {
512        AW_copy_GC_colors(aww->get_root(), "ARB_EDIT4", "ARB_SECEDIT",
513                          "User1",   "User2",   "Probe",
514                          "Primerl", "Primerr", "Primerg",
515                          "Sigl",    "Sigr",    "Sigg",
516                          "MISMATCHES",
517                          NULL);
518    }
519    if (which & COLOR_SYNC_RANGE) {
520        AW_copy_GC_colors(aww->get_root(), "ARB_EDIT4", "ARB_SECEDIT",
521                          "RANGE_0", "RANGE_1", "RANGE_2",
522                          "RANGE_3", "RANGE_4", "RANGE_5",
523                          "RANGE_6", "RANGE_7", "RANGE_8",
524                          "RANGE_9",
525                          NULL);
526    }
527    if (which & COLOR_SYNC_REST) {
528        AW_copy_GC_colors(aww->get_root(), "ARB_EDIT4", "ARB_SECEDIT",
529                          "CURSOR",
530                          NULL);
531    }
532}
533
534static AW_window *SEC_create_bonddef_window(AW_root *awr) {
535    AW_window_simple *aws = new AW_window_simple;
536
537    aws->init(awr, "SEC_BONDDEF", "Bond definitions");
538    aws->load_xfig("sec_bonddef.fig");
539
540    aws->at("close");
541    aws->callback(AW_POPDOWN);
542    aws->create_button("CLOSE", "CLOSE", "C");
543
544    aws->callback(makeHelpCallback("sec_bonddef.hlp"));
545    aws->at("help");
546    aws->create_button("HELP", "HELP", "H");
547
548    aws->at("label"); int x_label = aws->get_at_xposition();
549    aws->at("pairs"); int x_pairs = aws->get_at_xposition();
550    aws->at("chars"); int x_chars = aws->get_at_xposition();
551
552    aws->auto_space(0, 0);
553
554#define INSERT_PAIR_FIELDS(label, pairname)                             \
555    aws->at_x(x_label);                                                 \
556    aws->create_button(NULL, label);                                    \
557    aws->at_x(x_pairs);                                                 \
558    aws->create_input_field(AWAR_SECEDIT_##pairname##_PAIRS, 30);       \
559    aws->at_x(x_chars);                                                 \
560    aws->create_input_field(AWAR_SECEDIT_##pairname##_PAIR_CHAR, 1);    \
561    aws->at_newline();
562
563    INSERT_PAIR_FIELDS("Strong pairs", STRONG);
564    INSERT_PAIR_FIELDS("Normal pairs", NORMAL);
565    INSERT_PAIR_FIELDS("Weak pairs",   WEAK);
566    INSERT_PAIR_FIELDS("No pairs",     NO);
567    INSERT_PAIR_FIELDS("User pairs",   USER);
568
569#undef INSERT_PAIR_FIELDS
570
571    return aws;
572}
573
574#define INSERT_PAIR_MAPPING(pairname)                              \
575    { AWAR_SECEDIT_##pairname##_PAIRS, "pairs_" #pairname },       \
576    { AWAR_SECEDIT_##pairname##_PAIR_CHAR, "char_" #pairname }
577
578static AWT_config_mapping_def secedit_display_config_mapping[] = {
579    { AWAR_SECEDIT_HIDE_BASES,        "hidebases" },
580    { AWAR_SECEDIT_DIST_BETW_STRANDS, "stranddist" },
581    { AWAR_SECEDIT_SHOW_BONDS,        "showbonds" },
582
583    INSERT_PAIR_MAPPING(STRONG),
584    INSERT_PAIR_MAPPING(NORMAL),
585    INSERT_PAIR_MAPPING(WEAK),
586    INSERT_PAIR_MAPPING(NO),
587    INSERT_PAIR_MAPPING(USER),
588
589    { AWAR_SECEDIT_BOND_THICKNESS,     "bondthickness" },
590    { AWAR_SECEDIT_SHOW_CURPOS,        "showposition" },
591    { AWAR_SECEDIT_SHOW_HELIX_NRS,     "showhelixnrs" },
592    { AWAR_SECEDIT_SHOW_ECOLI_POS,     "showecolipos" },
593    { AWAR_SECEDIT_DISPLAY_SEARCH,     "showsearch" },
594    { AWAR_SECEDIT_DISPLAY_SAI,        "showsai" },
595    { AWAR_SECEDIT_DISPPOS_BINDING,    "disppos_helix" },
596    { AWAR_SECEDIT_DISPPOS_ECOLI,      "disppos_ecoli" },
597    { AWAR_SECEDIT_SHOW_STR_SKELETON,  "skeleton" },
598    { AWAR_SECEDIT_SKELETON_THICKNESS, "skeleton_thickness" },
599
600    { 0, 0 }
601};
602
603#undef INSERT_PAIR_MAPPING
604
605static AW_window *SEC_create_display_window(AW_root *awr) {
606    AW_window_simple *aws = new AW_window_simple;
607
608    const int SCALED_TEXT_COLUMNS = 7;
609    const int SCALER_WIDTH        = 200;
610
611    aws->auto_space(5, 5);
612
613    aws->init(awr, "SEC_DISPLAY_OPTS", "Display options");
614    aws->load_xfig("sec_display.fig");
615
616    aws->at("close");
617    aws->callback(AW_POPDOWN);
618    aws->create_button("CLOSE", "CLOSE", "C");
619
620    aws->callback(makeHelpCallback("sec_display.hlp"));
621    aws->at("help");
622    aws->create_button("HELP", "HELP", "H");
623
624    // ----------------------------------------
625
626    aws->at("bases");
627    aws->label("Display bases              :");
628    aws->create_inverse_toggle(AWAR_SECEDIT_HIDE_BASES);
629
630    aws->at("strand_dist");
631    aws->label("Distance between strands   :");
632    aws->create_input_field_with_scaler(AWAR_SECEDIT_DIST_BETW_STRANDS, SCALED_TEXT_COLUMNS, SCALER_WIDTH, AW_SCALER_EXP_LOWER);
633
634    aws->at("bonds");
635    aws->label("Display bonds");
636    aws->create_option_menu(AWAR_SECEDIT_SHOW_BONDS, true);
637    aws->insert_option("None",       "n", SHOW_NO_BONDS);
638    aws->insert_option("Helix",      "h", SHOW_HELIX_BONDS);
639    aws->insert_option("+Non-helix", "o", SHOW_NHELIX_BONDS);
640    aws->update_option_menu();
641
642    aws->at("bonddef");
643    aws->callback(makeCreateWindowCallback(SEC_create_bonddef_window));
644    aws->create_button("sec_bonddef", "Define", 0);
645
646    aws->at("bondThickness");
647    aws->label("Bond thickness             :");
648    aws->create_input_field_with_scaler(AWAR_SECEDIT_BOND_THICKNESS, SCALED_TEXT_COLUMNS, SCALER_WIDTH, AW_SCALER_EXP_LOWER);
649
650    // ----------------------------------------
651
652    aws->at("cursor");
653    aws->label("Annotate cursor            :");
654    aws->create_option_menu(AWAR_SECEDIT_SHOW_CURPOS, true);
655    aws->insert_option("None",     "n", SHOW_NO_CURPOS);
656    aws->insert_option("Absolute", "a", SHOW_ABS_CURPOS);
657    aws->insert_option("Ecoli",    "e", SHOW_ECOLI_CURPOS);
658    aws->insert_option("Base",     "b", SHOW_BASE_CURPOS);
659    aws->update_option_menu();
660
661    aws->at("helixNrs");
662    aws->label("Annotate helices           :");
663    aws->create_toggle(AWAR_SECEDIT_SHOW_HELIX_NRS);
664
665    aws->at("ecoli");
666    aws->label("Annotate ecoli positions   :");
667    aws->create_toggle(AWAR_SECEDIT_SHOW_ECOLI_POS);
668
669    aws->at("search");
670    aws->label("Visualize search results   :");
671    aws->create_toggle(AWAR_SECEDIT_DISPLAY_SEARCH);
672
673    aws->at("sai");
674    aws->label("Visualize SAI              :");
675    aws->create_toggle(AWAR_SECEDIT_DISPLAY_SAI);
676
677    // ----------------------------------------
678
679    aws->at("binding");
680    aws->label("Binding helix positions    :");
681    aws->create_toggle(AWAR_SECEDIT_DISPPOS_BINDING);
682
683    aws->at("ecoli2");
684    aws->label("Ecoli base positions       :");
685    aws->create_toggle(AWAR_SECEDIT_DISPPOS_ECOLI);
686
687    // ----------------------------------------
688
689    aws->at("strSkeleton");
690    aws->label("Display structure skeleton :");
691    aws->create_toggle(AWAR_SECEDIT_SHOW_STR_SKELETON);
692
693    aws->at("skelThickness");
694    aws->label("Skeleton thickness         :");
695    aws->create_input_field_with_scaler(AWAR_SECEDIT_SKELETON_THICKNESS, SCALED_TEXT_COLUMNS, SCALER_WIDTH, AW_SCALER_EXP_LOWER);
696
697#ifdef DEBUG
698    aws->at("show_debug");
699    aws->label("Show debug info:");
700    aws->create_toggle(AWAR_SECEDIT_SHOW_DEBUG);
701#endif
702
703    aws->at("config");
704    AWT_insert_config_manager(aws, AW_ROOT_DEFAULT, "secedit_display", secedit_display_config_mapping);
705
706    return aws;
707}
708
709#if defined(WARN_TODO)
710#warning use popdown callback for SEC_exit and valgrind open/close/open secedit
711#endif
712
713static void SEC_exit(GBDATA *, void *cl_sec_root) {
714    SEC_root *sec_root = static_cast<SEC_root*>(cl_sec_root);
715    delete sec_root;
716}
717
718static AW_window *SEC_create_gc_window(AW_root *awr, AW_gc_manager *gcman) {
719    return AW_create_gc_window_named(awr, gcman, "SECEDIT_COLOR_DEF", "SECEDIT colors and fonts");
720}
721
722AW_window *start_SECEDIT_plugin(ED4_plugin_host& host) {
723    AW_root *awr     = host.get_application_root();
724    GBDATA  *gb_main = host.get_database();
725
726    SEC_graphic *gfx  = new SEC_graphic(awr, gb_main); // never freed
727    SEC_root    *root = gfx->sec_root;
728
729    AW_window_menu_modes *awm = new AW_window_menu_modes;
730    awm->init(awr, "ARB_SECEDIT", "ARB_SECEDIT: Secondary structure editor", 200, 200);
731
732    AWT_canvas *scr = new AWT_canvas(gb_main, awm, awm->get_window_id(), gfx, AWAR_SPECIES_NAME);
733    root->init(gfx, scr, host);
734
735    scr->recalc_size(true);
736    scr->set_mode(AWT_MODE_ZOOM); // Default-Mode
737
738    const SEC_db_interface *db = root->get_db();
739
740    GB_atclose(gb_main, SEC_exit, root);
741
742    awm->create_menu("File", "F", AWM_ALL);
743
744    awm->insert_menu_topic("secedit_new",    "New structure",    "N", 0, AWM_ALL, makeWindowCallback(SEC_new_structure,    db));
745    awm->insert_menu_topic("secedit_rename", "Rename structure", "R", 0, AWM_ALL, makeWindowCallback(SEC_rename_structure, db));
746    awm->insert_menu_topic("secedit_delete", "Delete structure", "D", 0, AWM_ALL, makeWindowCallback(SEC_delete_structure, db));
747    awm->sep______________();
748    awm->insert_menu_topic("secedit_import", "Load structure", "L", "secedit_imexport.hlp", AWM_ALL, makeCreateWindowCallback(SEC_importExport, false, db));
749    awm->insert_menu_topic("secedit_export", "Save structure", "S", "secedit_imexport.hlp", AWM_ALL, makeCreateWindowCallback(SEC_importExport, true, db));
750    awm->sep______________();
751    awm->insert_menu_topic("secStruct2xfig", "Export structure to XFIG", "X", "tree2file.hlp", AWM_ALL, makeWindowCallback(AWT_popup_sec_export_window, scr));
752    awm->insert_menu_topic("print_secedit",  "Print Structure",          "P", "tree2prt.hlp",  AWM_ALL, makeWindowCallback(AWT_popup_print_window,      scr));
753    awm->sep______________();
754
755    awm->insert_menu_topic("close", "Close", "C", "quit.hlp", AWM_ALL, AW_POPDOWN);
756
757    awm->create_menu("Properties", "P", AWM_ALL);
758    awm->insert_menu_topic("sec_display", "Display options", "D", "sec_display.hlp", AWM_ALL, SEC_create_display_window);
759    awm->sep______________();
760    awm->insert_menu_topic("props_secedit", "Change Colors and Fonts", "C", "color_props.hlp", AWM_ALL, makeCreateWindowCallback(SEC_create_gc_window, scr->gc_manager));
761    awm->sep______________();
762    awm->insert_menu_topic("sync_search_colors", "Sync search colors with EDIT4", "s", "sync_colors.hlp", AWM_ALL, makeWindowCallback(SEC_sync_colors, COLOR_SYNC_SEARCH));
763    awm->insert_menu_topic("sync_range_colors",  "Sync range colors with EDIT4",  "r", "sync_colors.hlp", AWM_ALL, makeWindowCallback(SEC_sync_colors, COLOR_SYNC_RANGE));
764    awm->insert_menu_topic("sync_other_colors",  "Sync other colors with EDIT4",  "o", "sync_colors.hlp", AWM_ALL, makeWindowCallback(SEC_sync_colors, COLOR_SYNC_REST));
765    awm->insert_menu_topic("sync_all_colors",    "Sync all colors with EDIT4",    "a", "sync_colors.hlp", AWM_ALL, makeWindowCallback(SEC_sync_colors, COLOR_SYNC_ALL));
766    awm->sep______________();
767    awm->insert_menu_topic("sec_save_props",    "How to save properties",   "p", "savedef.hlp", AWM_ALL, makeHelpCallback("sec_props.hlp"));
768
769    awm->create_mode("mode_zoom.xpm",    "sec_mode.hlp", AWM_ALL, makeWindowCallback(sec_mode_event, root, AWT_MODE_ZOOM));
770    awm->create_mode("mode_fold.xpm",    "sec_mode.hlp", AWM_ALL, makeWindowCallback(sec_mode_event, root, AWT_MODE_FOLD));
771    awm->create_mode("mode_setroot.xpm", "sec_mode.hlp", AWM_ALL, makeWindowCallback(sec_mode_event, root, AWT_MODE_SETROOT));
772    awm->create_mode("mode_rotate.xpm",  "sec_mode.hlp", AWM_ALL, makeWindowCallback(sec_mode_event, root, AWT_MODE_ROTATE));
773    awm->create_mode("mode_stretch.xpm", "sec_mode.hlp", AWM_ALL, makeWindowCallback(sec_mode_event, root, AWT_MODE_STRETCH));
774    awm->create_mode("mode_edit.xpm",    "sec_mode.hlp", AWM_ALL, makeWindowCallback(sec_mode_event, root, AWT_MODE_EDIT));
775    awm->create_mode("mode_cursor.xpm",  "sec_mode.hlp", AWM_ALL, makeWindowCallback(sec_mode_event, root, AWT_MODE_CURSOR));
776    awm->create_mode("mode_pinfo.xpm",   "sec_mode.hlp", AWM_ALL, makeWindowCallback(sec_mode_event, root, AWT_MODE_PINFO));
777
778    awm->set_info_area_height(250);
779    awm->at(5, 2);
780    awm->auto_space(0, -2);
781
782    awm->button_length(0);
783    awm->help_text("quit.hlp");
784    awm->callback(AW_POPDOWN);
785    awm->create_button("Close", "#quit.xpm"); // use quit button, cause users regard secedit as separate program
786
787    awm->callback(AW_help_entry_pressed);
788    awm->help_text("arb_secedit.hlp");
789    awm->create_button("HELP", "#help.xpm");
790
791    awm->callback(makeWindowCallback(SEC_undo_cb, db, GB_UNDO_UNDO));
792    awm->help_text("undo.hlp");
793    awm->create_button("Undo", "#undo.xpm");
794
795    awm->callback(makeWindowCallback(SEC_undo_cb, db, GB_UNDO_REDO));
796    awm->help_text("undo.hlp");
797    awm->create_button("Redo", "#redo.xpm");
798
799    awm->callback(makeWindowCallback(SEC_toggle_cb, db));
800    awm->help_text("sec_main.hlp");
801    awm->create_button("Toggle", "Toggle");
802
803    awm->callback(makeWindowCallback(SEC_center_cb, root));
804    awm->help_text("sec_main.hlp");
805    awm->create_button("Center", "Center");
806
807    awm->callback(makeWindowCallback(SEC_fit_window_cb, db));
808    awm->help_text("sec_main.hlp");
809    awm->create_button("fitWindow", "Fit");
810
811    awm->at_newline();
812
813    {
814        SmartPtr<AW_at_storage> maxSize(AW_at_storage::make(awm, AW_AT_MAXSIZE));
815
816        awm->button_length(AWAR_FOOTER_MAX_LEN);
817        awm->create_button(0, AWAR_FOOTER);
818        awm->at_newline();
819        awm->restore_at_from(*maxSize);
820    }
821
822    awm->set_info_area_height(awm->get_at_yposition());
823
824    return awm;
825}
826
Note: See TracBrowser for help on using the repository browser.