source: branches/profile/SECEDIT/SEC_main.cxx

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