structure_window.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:66k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: structure_window.cpp,v $
  4.  * PRODUCTION Revision 1000.3  2004/06/01 18:29:33  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.33
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: structure_window.cpp,v 1000.3 2004/06/01 18:29:33 gouriano Exp $
  10. * ===========================================================================
  11. *
  12. *                            PUBLIC DOMAIN NOTICE
  13. *               National Center for Biotechnology Information
  14. *
  15. *  This software/database is a "United States Government Work" under the
  16. *  terms of the United States Copyright Act.  It was written as part of
  17. *  the author's official duties as a United States Government employee and
  18. *  thus cannot be copyrighted.  This software/database is freely available
  19. *  to the public for use. The National Library of Medicine and the U.S.
  20. *  Government have not placed any restriction on its use or reproduction.
  21. *
  22. *  Although all reasonable efforts have been taken to ensure the accuracy
  23. *  and reliability of the software and data, the NLM and the U.S.
  24. *  Government do not and cannot warrant the performance or results that
  25. *  may be obtained by using this software or data. The NLM and the U.S.
  26. *  Government disclaim all warranties, express or implied, including
  27. *  warranties of performance, merchantability or fitness for any particular
  28. *  purpose.
  29. *
  30. *  Please cite the author in any work or product based on this material.
  31. *
  32. * ===========================================================================
  33. *
  34. * Authors:  Paul Thiessen
  35. *
  36. * File Description:
  37. *      structure window object for Cn3D
  38. *
  39. * ===========================================================================
  40. */
  41. #ifdef _MSC_VER
  42. #pragma warning(disable:4018)   // disable signed/unsigned mismatch warning in MSVC
  43. #endif
  44. #include <ncbi_pch.hpp>
  45. #include <corelib/ncbistd.hpp>
  46. #include <corelib/ncbitime.hpp> // avoids some 'CurrentTime' conflict later on...
  47. #include <objects/ncbimime/Ncbi_mime_asn1.hpp>
  48. #include <objects/cdd/Cdd.hpp>
  49. #include <objects/mmdb2/Model_type.hpp>
  50. #include <algorithm>
  51. #include <memory>
  52. #ifdef __WXMSW__
  53. #include <windows.h>
  54. #include <wx/msw/winundef.h>
  55. #endif
  56. #include <wx/wx.h>
  57. #include <wx/html/helpfrm.h>
  58. #include <wx/html/helpctrl.h>
  59. #include <wx/fontdlg.h>
  60. #include <wx/confbase.h>
  61. #include <wx/fileconf.h>
  62. #include <wx/filename.h>
  63. #include <wx/choicdlg.h>
  64. #include "asn_reader.hpp"
  65. #include "cn3d_glcanvas.hpp"
  66. #include "structure_window.hpp"
  67. #include "structure_set.hpp"
  68. #include "opengl_renderer.hpp"
  69. #include "style_manager.hpp"
  70. #include "messenger.hpp"
  71. #include "chemical_graph.hpp"
  72. #include "alignment_manager.hpp"
  73. #include "show_hide_manager.hpp"
  74. #include "show_hide_dialog.hpp"
  75. #include "cn3d_tools.hpp"
  76. #include "cdd_annot_dialog.hpp"
  77. #include "preferences_dialog.hpp"
  78. #include "cdd_ref_dialog.hpp"
  79. #include "cdd_book_ref_dialog.hpp"
  80. #include "cn3d_png.hpp"
  81. #include "wx_tools.hpp"
  82. #include "block_multiple_alignment.hpp"
  83. #include "sequence_set.hpp"
  84. #include "molecule_identifier.hpp"
  85. #include "cdd_splash_dialog.hpp"
  86. #include "command_processor.hpp"
  87. #include "animation_controls.hpp"
  88. #include "cn3d_cache.hpp"
  89. // the application icon (under Windows it is in resources)
  90. #if defined(__WXGTK__) || defined(__WXMAC__)
  91.     #include "cn3d.xpm"
  92. #endif
  93. #include <ncbienv.h>
  94. USING_NCBI_SCOPE;
  95. USING_SCOPE(objects);
  96. BEGIN_SCOPE(Cn3D)
  97. // global strings
  98. static string
  99.     userDir,        // directory of latest user-selected file
  100.     currentFile;    // name of current working file
  101. const string& GetUserDir(void) { return userDir; }
  102. const string& GetWorkingFilename(void) { return currentFile; }
  103. // global working title
  104. static string workingTitle;
  105. const string& GetWorkingTitle(void) { return workingTitle; }
  106. static void SetWorkingTitle(StructureSet *sSet)
  107. {
  108.     if (sSet->IsCDDInMime() && sSet->GetCDDName().size() > 0)
  109.         workingTitle = sSet->GetCDDName();      // for CDD's sent by server
  110.     else if (sSet->IsCDD())
  111.         workingTitle = GetWorkingFilename();    // for CDD's edited by curators
  112.     else if (sSet->objects.size() > 0) {
  113.         workingTitle = sSet->objects.front()->pdbID;
  114.         if (sSet->objects.size() > 1)
  115.             workingTitle += " neighbors";
  116.     } else
  117.         workingTitle = GetWorkingFilename();
  118. }
  119. // favorites stuff
  120. static bool favoriteStylesChanged = false;
  121. static CCn3d_style_settings_set favoriteStyles;
  122. static bool LoadFavorites(void);
  123. static void SaveFavorites(void);
  124. BEGIN_EVENT_TABLE(StructureWindow, wxFrame)
  125.     EVT_CLOSE     (                                         StructureWindow::OnCloseWindow)
  126.     EVT_MENU      (MID_EXIT,                                StructureWindow::OnExit)
  127.     EVT_MENU_RANGE(MID_OPEN, MID_NETWORK_OPEN,              StructureWindow::OnOpen)
  128.     EVT_MENU_RANGE(MID_SAVE_SAME, MID_SAVE_AS,              StructureWindow::OnSave)
  129.     EVT_MENU      (MID_PNG,                                 StructureWindow::OnPNG)
  130.     EVT_MENU_RANGE(MID_ZOOM_IN,  MID_STEREO,                StructureWindow::OnAdjustView)
  131.     EVT_MENU_RANGE(MID_SHOW_HIDE,  MID_SELECT_MOLECULE,     StructureWindow::OnShowHide)
  132.     EVT_MENU_RANGE(MID_DIST_SELECT_RESIDUES, MID_DIST_SELECT_OTHER_ALL, StructureWindow::OnDistanceSelect)
  133.     EVT_MENU      (MID_REFIT_ALL,                           StructureWindow::OnAlignStructures)
  134.     EVT_MENU_RANGE(MID_EDIT_STYLE, MID_ANNOTATE,            StructureWindow::OnSetStyle)
  135.     EVT_MENU_RANGE(MID_ADD_FAVORITE, MID_FAVORITES_FILE,    StructureWindow::OnEditFavorite)
  136.     EVT_MENU_RANGE(MID_FAVORITES_BEGIN, MID_FAVORITES_END,  StructureWindow::OnSelectFavorite)
  137.     EVT_MENU_RANGE(MID_SHOW_LOG,   MID_SHOW_SEQ_V,          StructureWindow::OnShowWindow)
  138.     EVT_MENU_RANGE(MID_CDD_OVERVIEW, MID_CDD_SHOW_REJECTS,  StructureWindow::OnCDD)
  139.     EVT_MENU      (MID_PREFERENCES,                         StructureWindow::OnPreferences)
  140.     EVT_MENU_RANGE(MID_OPENGL_FONT, MID_SEQUENCE_FONT,      StructureWindow::OnSetFont)
  141.     EVT_MENU_RANGE(MID_PLAY, MID_ANIM_CONTROLS,             StructureWindow::OnAnimate)
  142.     EVT_MENU_RANGE(MID_HELP_COMMANDS, MID_ONLINE_HELP,      StructureWindow::OnHelp)
  143.     EVT_MENU      (MID_ABOUT,                               StructureWindow::OnHelp)
  144.     EVT_TIMER     (MID_ANIMATE,                             StructureWindow::OnAnimationTimer)
  145.     EVT_TIMER     (MID_MESSAGING,                           StructureWindow::OnFileMessagingTimer)
  146.     EVT_MENU      (MID_SEND_SELECTION,                      StructureWindow::OnSendSelection)
  147. END_EVENT_TABLE()
  148. StructureWindow::StructureWindow(const wxString& title, const wxPoint& pos, const wxSize& size) :
  149.     wxFrame(NULL, wxID_HIGHEST + 1, title, pos, size, wxDEFAULT_FRAME_STYLE | wxTHICK_FRAME),
  150.     glCanvas(NULL), cddAnnotateDialog(NULL), cddDescriptionDialog(NULL), cddNotesDialog(NULL),
  151.     cddRefDialog(NULL), cddBookRefDialog(NULL), helpController(NULL), helpConfig(NULL),
  152.     cddOverview(NULL), fileMessagingManager("Cn3D"), fileMessenger(NULL), spinIncrement(3.0)
  153. {
  154.     GlobalMessenger()->AddStructureWindow(this);
  155.     animationTimer.SetOwner(this, MID_ANIMATE);
  156.     SetSizeHints(150, 150); // min size
  157.     SetIcon(wxICON(cn3d));
  158.     commandProcessor = new CommandProcessor(this);
  159.     // File menu
  160.     menuBar = new wxMenuBar;
  161.     fileMenu = new wxMenu;
  162.     fileMenu->Append(MID_OPEN, "&OpentCtrl+O");
  163.     fileMenu->Append(MID_NETWORK_OPEN, "&Network LoadtCtrl+N");
  164.     fileMenu->Append(MID_SAVE_SAME, "&SavetCtrl+S");
  165.     fileMenu->Append(MID_SAVE_AS, "Save &As...");
  166.     fileMenu->Append(MID_PNG, "&Export PNG");
  167.     fileMenu->AppendSeparator();
  168.     fileMenu->Append(MID_REFIT_ALL, "&Realign Structures");
  169.     fileMenu->AppendSeparator();
  170.     fileMenu->Append(MID_PREFERENCES, "&Preferences...");
  171.     wxMenu *subMenu = new wxMenu;
  172.     subMenu->Append(MID_OPENGL_FONT, "S&tructure Window");
  173.     subMenu->Append(MID_SEQUENCE_FONT, "Se&quence Windows");
  174.     fileMenu->Append(MID_FONTS, "Set &Fonts...", subMenu);
  175.     fileMenu->AppendSeparator();
  176.     fileMenu->Append(MID_EXIT, "E&xit");
  177.     menuBar->Append(fileMenu, "&File");
  178.     // View menu
  179.     wxMenu *menu = new wxMenu;
  180.     menu->Append(MID_ZOOM_IN, "Zoom &Intz");
  181.     menu->Append(MID_ZOOM_OUT, "Zoom &Outtx");
  182.     menu->Append(MID_RESTORE, "&Restore");
  183.     menu->Append(MID_RESET, "Rese&t");
  184.     menu->AppendSeparator();
  185. #ifdef __WXMSW__
  186.     menu->Append(MID_NEXT_FRAME, "&Next FrametRight");
  187.     menu->Append(MID_PREV_FRAME, "Pre&vious FrametLeft");
  188.     menu->Append(MID_FIRST_FRAME, "&First FrametDown");
  189.     menu->Append(MID_LAST_FRAME, "&Last FrametUp");
  190. #else
  191.     // other platforms don't like to display these long accelerator names
  192.     menu->Append(MID_NEXT_FRAME, "&Next Frame");
  193.     menu->Append(MID_PREV_FRAME, "Pre&vious Frame");
  194.     menu->Append(MID_FIRST_FRAME, "&First Frame");
  195.     menu->Append(MID_LAST_FRAME, "&Last Frame");
  196. #endif
  197.     menu->Append(MID_ALL_FRAMES, "&All Framesta");
  198.     menu->AppendSeparator();
  199.     subMenu = new wxMenu;
  200.     subMenu->Append(MID_PLAY, "&Play Framestp", "", true);
  201.     subMenu->Check(MID_PLAY, false);
  202.     subMenu->Append(MID_SPIN, "Spi&ntn", "", true);
  203.     subMenu->Check(MID_SPIN, false);
  204.     subMenu->Append(MID_STOP, "&Stopts", "", true);
  205.     subMenu->Check(MID_STOP, true);
  206.     subMenu->AppendSeparator();
  207.     subMenu->Append(MID_ANIM_CONTROLS, "Set Spee&d");
  208.     menu->Append(MID_ANIMATE, "Ani&mation", subMenu);
  209.     menu->AppendSeparator();
  210.     menu->Append(MID_STEREO, "St&ereo", "", true);
  211.     menuBar->Append(menu, "&View");
  212.     // Show-Hide menu
  213.     menu = new wxMenu;
  214.     menu->Append(MID_SHOW_HIDE, "&Pick Structures...");
  215.     menu->AppendSeparator();
  216.     menu->Append(MID_SHOW_ALL, "Show &Everythingte");
  217.     menu->Append(MID_SHOW_DOMAINS, "Show Aligned &Domainstd");
  218.     menu->Append(MID_SHOW_ALIGNED, "Show &Aligned Residues");
  219.     menu->Append(MID_SHOW_SELECTED_RESIDUES, "Show &Selected Residues");
  220.     menu->Append(MID_SHOW_SELECTED_DOMAINS, "Show Selected Do&mains");
  221.     subMenu = new wxMenu;
  222.     subMenu->Append(MID_SHOW_UNALIGNED_ALL, "Show &All");
  223.     subMenu->Append(MID_SHOW_UNALIGNED_ALN_DOMAIN, "Show in Aligned &Domains");
  224.     menu->Append(MID_SHOW_UNALIGNED, "&Unaligned Residues", subMenu);
  225.     menu->AppendSeparator();
  226.     subMenu = new wxMenu;
  227.     subMenu->Append(MID_DIST_SELECT_RESIDUES, "&Residues Only");
  228.     subMenu->Append(MID_DIST_SELECT_ALL, "&All Molecules");
  229.     subMenu->Append(MID_DIST_SELECT_OTHER_RESIDUES, "&Other Residues");
  230.     subMenu->Append(MID_DIST_SELECT_OTHER_ALL, "Other &Molecules");
  231.     menu->Append(MID_DIST_SELECT, "Select by Dis&tance...", subMenu);
  232.     menu->Append(MID_SELECT_MOLECULE, "Select Molecule...tm");
  233.     menuBar->Append(menu, "Show/&Hide");
  234.     // Style menu
  235.     menu = new wxMenu;
  236.     menu->Append(MID_EDIT_STYLE, "Edit &Global Style");
  237.     // favorites
  238.     favoritesMenu = new wxMenu;
  239.     favoritesMenu->Append(MID_ADD_FAVORITE, "&Add/Replace");
  240.     favoritesMenu->Append(MID_REMOVE_FAVORITE, "&Remove");
  241.     favoritesMenu->Append(MID_FAVORITES_FILE, "&Change File");
  242.     favoritesMenu->AppendSeparator();
  243.     LoadFavorites();
  244.     SetupFavoritesMenu();
  245.     menu->Append(MID_FAVORITES, "&Favorites", favoritesMenu);
  246.     // rendering shortcuts
  247.     subMenu = new wxMenu;
  248.     subMenu->Append(MID_WORM, "&Worms", "", true);
  249.     subMenu->Append(MID_TUBE, "&Tubes", "", true);
  250.     subMenu->Append(MID_WIRE, "Wir&e", "", true);
  251.     subMenu->Append(MID_BNS, "&Ball and Stick", "", true);
  252.     subMenu->Append(MID_SPACE, "&Space Fill", "", true);
  253.     subMenu->AppendSeparator();
  254.     subMenu->Append(MID_SC_TOGGLE, "&Toggle Sidechains");
  255.     menu->Append(MID_RENDER, "&Rendering Shortcuts", subMenu);
  256.     // coloring shortcuts
  257.     subMenu = new wxMenu;
  258.     subMenu->Append(MID_SECSTRUC, "&Secondary Structure", "", true);
  259.     subMenu->Append(MID_ALIGNED, "&Aligned", "", true);
  260.     wxMenu *subMenu2 = new wxMenu;
  261.     subMenu2->Append(MID_IDENTITY, "I&dentity", "", true);
  262.     subMenu2->Append(MID_VARIETY, "&Variety", "", true);
  263.     subMenu2->Append(MID_WGHT_VAR, "&Weighted Variety", "", true);
  264.     subMenu2->Append(MID_INFO, "&Information Content", "", true);
  265.     subMenu2->Append(MID_FIT, "&Fit", "", true);
  266.     subMenu2->Append(MID_BLOCK_FIT, "&Block Fit", "", true);
  267.     subMenu2->Append(MID_BLOCK_Z_FIT, "&Normalized Block Fit", "", true);
  268.     subMenu2->Append(MID_BLOCK_ROW_FIT, "Block &Row Fit", "", true);
  269.     subMenu->Append(MID_CONS, "Sequence &Conservation", subMenu2);
  270.     subMenu->Append(MID_OBJECT, "&Object", "", true);
  271.     subMenu->Append(MID_DOMAIN, "&Domain", "", true);
  272.     subMenu->Append(MID_MOLECULE, "&Molecule", "", true);
  273.     subMenu->Append(MID_RAINBOW, "&Rainbow", "", true);
  274.     subMenu->Append(MID_HYDROPHOB, "&Hydrophobicity", "", true);
  275.     subMenu->Append(MID_CHARGE, "Char&ge", "", true);
  276.     subMenu->Append(MID_TEMP, "&Temperature", "", true);
  277.     subMenu->Append(MID_ELEMENT, "&Element", "", true);
  278.     menu->Append(MID_COLORS, "&Coloring Shortcuts", subMenu);
  279.     //annotate
  280.     menu->AppendSeparator();
  281.     menu->Append(MID_ANNOTATE, "A&nnotate");
  282.     menuBar->Append(menu, "&Style");
  283.     // Window menu
  284.     windowMenu = new wxMenu;
  285.     windowMenu->Append(MID_SHOW_SEQ_V, "Show &Sequence Viewer");
  286.     windowMenu->Append(MID_SHOW_LOG, "Show Message &Log");
  287.     windowMenu->Append(MID_SHOW_LOG_START, "Show Log on Start&up", "", true);
  288.     bool showLog = false;
  289.     RegistryGetBoolean(REG_CONFIG_SECTION, REG_SHOW_LOG_ON_START, &showLog);
  290.     windowMenu->Check(MID_SHOW_LOG_START, showLog);
  291.     menuBar->Append(windowMenu, "&Window");
  292.     // CDD menu
  293.     bool readOnly;
  294.     RegistryGetBoolean(REG_ADVANCED_SECTION, REG_CDD_ANNOT_READONLY, &readOnly);
  295.     menu = new wxMenu;
  296.     menu->Append(MID_CDD_OVERVIEW, "CDD &Overview");
  297.     menu->AppendSeparator();
  298.     menu->Append(MID_EDIT_CDD_NAME, "Edit &Name");
  299.     menu->Enable(MID_EDIT_CDD_NAME, !readOnly);
  300.     menu->Append(MID_EDIT_CDD_DESCR, "Edit &Description");
  301.     menu->Enable(MID_EDIT_CDD_DESCR, !readOnly);
  302.     menu->Append(MID_EDIT_CDD_NOTES, "Edit No&tes");
  303.     menu->Enable(MID_EDIT_CDD_NOTES, !readOnly);
  304.     menu->Append(MID_EDIT_CDD_REFERENCES, "Edit PubMed &References");
  305. //    menu->Enable(MID_EDIT_CDD_REFERENCES, !readOnly);
  306.     menu->Append(MID_EDIT_CDD_BOOK_REFERENCES, "Edit &Book References");
  307. //    menu->Enable(MID_EDIT_CDD_BOOK_REFERENCES, !readOnly);
  308.     menu->Append(MID_ANNOT_CDD, "Edit &Annotations");
  309.     menu->Enable(MID_ANNOT_CDD, !readOnly);
  310.     menu->AppendSeparator();
  311.     menu->Append(MID_CDD_REJECT_SEQ, "Re&ject Sequence");
  312.     menu->Enable(MID_CDD_REJECT_SEQ, !readOnly);
  313.     menu->Append(MID_CDD_SHOW_REJECTS, "&Show Rejects");
  314.     menuBar->Append(menu, "&CDD");
  315.     // Help menu
  316.     menu = new wxMenu;
  317.     menu->Append(MID_HELP_COMMANDS, "&Commands");
  318.     menu->Append(MID_ONLINE_HELP, "Online &Help...");
  319.     menu->Append(MID_ABOUT, "&About");
  320.     menuBar->Append(menu, "&Help");
  321.     // accelerators for special keys
  322.     wxAcceleratorEntry entries[12];
  323.     entries[0].Set(wxACCEL_NORMAL, WXK_RIGHT, MID_NEXT_FRAME);
  324.     entries[1].Set(wxACCEL_NORMAL, WXK_LEFT, MID_PREV_FRAME);
  325.     entries[2].Set(wxACCEL_NORMAL, WXK_DOWN, MID_FIRST_FRAME);
  326.     entries[3].Set(wxACCEL_NORMAL, WXK_UP, MID_LAST_FRAME);
  327.     entries[4].Set(wxACCEL_NORMAL, 'z', MID_ZOOM_IN);
  328.     entries[5].Set(wxACCEL_NORMAL, 'x', MID_ZOOM_OUT);
  329.     entries[6].Set(wxACCEL_NORMAL, 'a', MID_ALL_FRAMES);
  330.     entries[7].Set(wxACCEL_NORMAL, 'p', MID_PLAY);
  331.     entries[8].Set(wxACCEL_NORMAL, 'n', MID_SPIN);
  332.     entries[9].Set(wxACCEL_NORMAL, 's', MID_STOP);
  333.     entries[10].Set(wxACCEL_NORMAL, 'e', MID_SHOW_ALL);
  334.     entries[11].Set(wxACCEL_NORMAL, 'd', MID_SHOW_DOMAINS);
  335.     wxAcceleratorTable accel(12, entries);
  336.     SetAcceleratorTable(accel);
  337.     // set menu bar and initial states
  338.     SetMenuBar(menuBar);
  339.     menuBar->EnableTop(menuBar->FindMenu("CDD"), false);
  340.     menuBar->Check(MID_STEREO, false);
  341.     // Make a GLCanvas
  342. #if defined(__WXMSW__)
  343.     int *attribList = NULL;
  344. #elif defined(__WXGTK__)
  345.     int *attribList = NULL;
  346. #elif defined(__WXMAC__)
  347.     int *attribList = NULL;
  348. #endif
  349.     glCanvas = new Cn3DGLCanvas(this, attribList);
  350.     // set initial font
  351.     Show(true); // on X, need to establish gl context first, which requires visible window
  352.     glCanvas->SetCurrent();
  353.     glCanvas->SetGLFontFromRegistry();
  354. }
  355. StructureWindow::~StructureWindow(void)
  356. {
  357.     delete commandProcessor;
  358. }
  359. void StructureWindow::OnCloseWindow(wxCloseEvent& event)
  360. {
  361.     animationTimer.Stop();
  362.     fileMessagingTimer.Stop();
  363.     Command(MID_EXIT);
  364. }
  365. void StructureWindow::OnExit(wxCommandEvent& event)
  366. {
  367.     animationTimer.Stop();
  368.     fileMessagingTimer.Stop();
  369.     GlobalMessenger()->RemoveStructureWindow(this); // don't bother with any redraws since we're exiting
  370.     GlobalMessenger()->SequenceWindowsSave(true);   // save any edited alignment and updates first
  371.     SaveDialog(true, false);                        // give structure window a chance to save data
  372.     SaveFavorites();
  373.     if (IsFileMessengerActive())
  374.         SendCommand(messageTargetApp, "Cn3DTerminated", "");
  375.     // remove help window if present
  376.     if (helpController) {
  377.         if (helpController->GetFrame())
  378.             helpController->GetFrame()->Close(true);
  379.         wxConfig::Set(NULL);
  380.         delete helpConfig; // saves data
  381.         delete helpController;
  382.     }
  383.     DestroyNonModalDialogs();
  384.     Destroy();
  385. }
  386. void StructureWindow::SetupFileMessenger(const std::string& messageFilename,
  387.     const std::string& messageApp, bool readOnly)
  388. {
  389.     if (fileMessenger) return;
  390.     // create messenger
  391.     fileMessenger = fileMessagingManager.CreateNewFileMessenger(messageFilename, this, readOnly);
  392.     fileMessagingTimer.SetOwner(this, MID_MESSAGING);
  393.     fileMessagingTimer.Start(200, false);
  394.     // add menu item for file messaging selection
  395.     messageTargetApp = messageApp;
  396.     windowMenu->AppendSeparator();
  397.     windowMenu->Append(MID_SEND_SELECTION, (string("Sen&d Selection to ") + messageTargetApp).c_str());
  398. }
  399. void StructureWindow::OnFileMessagingTimer(wxTimerEvent& event)
  400. {
  401.     // poll message files
  402.     fileMessagingManager.PollMessageFiles();
  403. }
  404. void StructureWindow::ReceivedCommand(const std::string& fromApp, unsigned long id,
  405.     const std::string& command, const std::string& data)
  406. {
  407.     INFOMSG("received command " << id << " from " << fromApp << ": " << command);
  408.     // default reply - should be changed by CommandProcessor
  409.     MessageResponder::ReplyStatus replyStatus = MessageResponder::REPLY_ERROR;
  410.     string replyData = "failed to processn";
  411.     // actually perform the command functions
  412.     commandProcessor->ProcessCommand(command, data, &replyStatus, &replyData);
  413.     // reply
  414.     INFOMSG("reply: " << ((replyStatus == MessageResponder::REPLY_OKAY) ? "OKAY" : "ERROR"));
  415.     if (replyData.size() > 0)
  416.         TRACEMSG("data:n" << replyData.substr(0, replyData.size() - 1));
  417.     else
  418.         TRACEMSG("data: (none)");
  419.     fileMessenger->SendReply(fromApp, id, replyStatus, replyData);
  420. }
  421. void StructureWindow::ReceivedReply(const std::string& fromApp, unsigned long id,
  422.     MessageResponder::ReplyStatus status, const std::string& data)
  423. {
  424.     // just post a message for now; eventually may pass on to CommandProcessor
  425.     if (status == MessageResponder::REPLY_OKAY)
  426.         INFOMSG(fromApp << ": got OKAY from " << fromApp << " (command " << id << "), data: " << data);
  427.     else
  428.         ERRORMSG(fromApp << ": got ERROR from " << fromApp << " (command " << id << "), data: " << data);
  429. }
  430. void StructureWindow::SendCommand(const std::string& toApp,
  431.     const std::string& command, const std::string& data)
  432. {
  433.     if (!IsFileMessengerActive()) {
  434.         ERRORMSG("SendCommand: no message file active!");
  435.         return;
  436.     }
  437.     // for now, just assign command id's in numerical order
  438.     static unsigned long nextCommandID = 1;
  439.     INFOMSG("sending command " << nextCommandID << " to " << toApp << ": " << command);
  440.     fileMessenger->SendCommand(toApp, ++nextCommandID, command, data);
  441. }
  442. void StructureWindow::OnSendSelection(wxCommandEvent& event)
  443. {
  444.     if (!fileMessenger) {
  445.         ERRORMSG("Can't send messages when return messaging is off");
  446.         return;
  447.     }
  448.     string data;
  449.     if (GlobalMessenger()->GetHighlightsForSelectionMessage(&data))
  450.         SendCommand(messageTargetApp, "Select", data);
  451. }
  452. void StructureWindow::SetWindowTitle(void)
  453. {
  454.     SetTitle(wxString(GetWorkingTitle().c_str()) + " - Cn3D " + CN3D_VERSION_STRING);
  455. }
  456. void StructureWindow::OnHelp(wxCommandEvent& event)
  457. {
  458.     if (event.GetId() == MID_HELP_COMMANDS) {
  459.         if (!helpController) {
  460.             wxString path = wxString(GetPrefsDir().c_str()) + "help_cache";
  461.             if (!wxDirExists(path)) {
  462.                 INFOMSG("trying to create help cache folder " << path.c_str());
  463.                 wxMkdir(path);
  464.             }
  465.             helpController = new wxHtmlHelpController(wxHF_DEFAULTSTYLE);
  466.             helpController->SetTempDir(path);
  467.             path = path + wxFILE_SEP_PATH + "Config";
  468.             INFOMSG("saving help config in " << path.c_str());
  469.             helpConfig = new wxFileConfig("Cn3D", "NCBI", path);
  470.             wxConfig::Set(helpConfig);
  471.             helpController->UseConfig(wxConfig::Get());
  472. #ifdef __WXMAC__
  473.             path = wxString(GetProgramDir().c_str()) + "../Resources/cn3d_commands.htb";
  474. #else
  475.             path = wxString(GetProgramDir().c_str()) + "cn3d_commands.htb";
  476. #endif
  477.             if (!helpController->AddBook(path))
  478.                 ERRORMSG("Can't load help book at " << path.c_str());
  479.         }
  480.         if (event.GetId() == MID_HELP_COMMANDS)
  481.             helpController->Display("Cn3D Commands");
  482.     }
  483.     else if (event.GetId() == MID_ONLINE_HELP) {
  484.         LaunchWebPage("http://www.ncbi.nlm.nih.gov/Structure/CN3D/cn3d.shtml");
  485.     }
  486.     else if (event.GetId() == MID_ABOUT) {
  487.         wxString message(
  488.             "Cn3D version "
  489.             CN3D_VERSION_STRING
  490.             "nn"
  491.             "Produced by the National Center for Biotechnology Informationn"
  492.             "     http://www.ncbi.nlm.nih.govnn"
  493.             "Please direct all questions and comments to:n"
  494.             "     info@ncbi.nlm.nih.gov"
  495.         );
  496.         wxMessageBox(message, "About Cn3D", wxOK | wxICON_INFORMATION, this);
  497.     }
  498. }
  499. void StructureWindow::OnDistanceSelect(wxCommandEvent& event)
  500. {
  501.     if (!glCanvas->structureSet) return;
  502.     static double latestCutoff = 5.0;
  503.     GetFloatingPointDialog dialog(this, "Enter a distance cutoff (in Angstroms):", "Distance?",
  504.         0.0, 1000.0, 0.5, latestCutoff);
  505.     if (dialog.ShowModal() == wxOK) {
  506.         latestCutoff = dialog.GetValue();
  507.         glCanvas->structureSet->SelectByDistance(latestCutoff,
  508.             (event.GetId() == MID_DIST_SELECT_RESIDUES || event.GetId() == MID_DIST_SELECT_OTHER_RESIDUES),
  509.             (event.GetId() == MID_DIST_SELECT_OTHER_RESIDUES || event.GetId() == MID_DIST_SELECT_OTHER_ALL));
  510.     }
  511. }
  512. void StructureWindow::OnPNG(wxCommandEvent& event)
  513. {
  514.     ExportPNG(glCanvas);
  515. }
  516. void StructureWindow::OnAnimate(wxCommandEvent& event)
  517. {
  518.     if (event.GetId() != MID_ANIM_CONTROLS) {
  519.         menuBar->Check(MID_PLAY, false);
  520.         menuBar->Check(MID_SPIN, false);
  521.         menuBar->Check(MID_STOP, true);
  522.     }
  523.     if (!glCanvas->structureSet) return;
  524.     // play frames
  525.     if (event.GetId() == MID_PLAY) {
  526.         if (glCanvas->structureSet->frameMap.size() > 1) {
  527.             int delay;
  528.             if (!RegistryGetInteger(REG_ANIMATION_SECTION, REG_FRAME_DELAY, &delay))
  529.                 return;
  530.             animationTimer.Start(delay, false);
  531.             animationMode = ANIM_FRAMES;
  532.             menuBar->Check(MID_PLAY, true);
  533.             menuBar->Check(MID_STOP, false);
  534.         }
  535.     }
  536.     // spin
  537.     if (event.GetId() == MID_SPIN) {
  538.         int delay;
  539.         if (!RegistryGetInteger(REG_ANIMATION_SECTION, REG_SPIN_DELAY, &delay) ||
  540.             !RegistryGetDouble(REG_ANIMATION_SECTION, REG_SPIN_INCREMENT, &spinIncrement))
  541.             return;
  542.         animationTimer.Start(delay, false);
  543.         animationMode = ANIM_SPIN;
  544.         menuBar->Check(MID_SPIN, true);
  545.         menuBar->Check(MID_STOP, false);
  546.     }
  547.     // stop
  548.     else if (event.GetId() == MID_STOP) {
  549.         animationTimer.Stop();
  550.     }
  551.     // controls
  552.     else if (event.GetId() == MID_ANIM_CONTROLS) {
  553.         AnimationControls dialog(this);
  554.         dialog.ShowModal();
  555.         // restart timer to pick up new settings
  556.         if (animationTimer.IsRunning()) {
  557.             animationTimer.Stop();
  558.             Command((animationMode == ANIM_SPIN) ? MID_SPIN : MID_PLAY);
  559.         }
  560.     }
  561. }
  562. void StructureWindow::OnAnimationTimer(wxTimerEvent& event)
  563. {
  564.     if (animationMode == ANIM_FRAMES) {
  565.         // simply pretend the user selected "next frame"
  566.         Command(MID_NEXT_FRAME);
  567.     }
  568.     else if (animationMode == ANIM_SPIN) {
  569.         // pretend the user dragged the mouse to the right
  570.         glCanvas->renderer->ChangeView(OpenGLRenderer::eXYRotateHV,
  571.             spinIncrement/glCanvas->renderer->GetRotateSpeed(), 0);
  572.         glCanvas->Refresh(false);
  573.     }
  574. }
  575. void StructureWindow::OnSetFont(wxCommandEvent& event)
  576. {
  577.     string section, faceName;
  578.     if (event.GetId() == MID_OPENGL_FONT)
  579.         section = REG_OPENGL_FONT_SECTION;
  580.     else if (event.GetId() == MID_SEQUENCE_FONT)
  581.         section = REG_SEQUENCE_FONT_SECTION;
  582.     else
  583.         return;
  584.     // get initial font info from registry, and create wxFont
  585.     string nativeFont;
  586.     RegistryGetString(section, REG_FONT_NATIVE_FONT_INFO, &nativeFont);
  587.     auto_ptr<wxFont> initialFont(wxFont::New(wxString(nativeFont.c_str())));
  588.     if (!initialFont.get() || !initialFont->Ok())
  589.     {
  590.         ERRORMSG("StructureWindow::OnSetFont() - error setting up initial font");
  591.         return;
  592.     }
  593.     wxFontData initialFontData;
  594.     initialFontData.SetInitialFont(*initialFont);
  595.     // bring up font chooser dialog
  596. #if wxCHECK_VERSION(2,3,3)
  597.     wxFontDialog dialog(this, initialFontData);
  598. #else
  599.     wxFontDialog dialog(this, &initialFontData);
  600. #endif
  601.     int result = dialog.ShowModal();
  602.     // if user selected a font
  603.     if (result == wxID_OK) {
  604.         // set registry values appropriately
  605.         wxFontData& fontData = dialog.GetFontData();
  606.         wxFont font = fontData.GetChosenFont();
  607.         if (!RegistrySetString(section, REG_FONT_NATIVE_FONT_INFO, font.GetNativeFontInfoDesc().c_str()))
  608.         {
  609.             ERRORMSG("StructureWindow::OnSetFont() - error setting registry data");
  610.             return;
  611.         }
  612.         // call font setup
  613.         INFOMSG("setting new font");
  614.         if (event.GetId() == MID_OPENGL_FONT) {
  615.             glCanvas->SetCurrent();
  616.             glCanvas->SetGLFontFromRegistry();
  617.             GlobalMessenger()->PostRedrawAllStructures();
  618.         } else if (event.GetId() == MID_SEQUENCE_FONT) {
  619.             GlobalMessenger()->NewSequenceViewerFont();
  620.         }
  621.     }
  622. }
  623. static string GetFavoritesFile(bool forRead)
  624. {
  625.     // try to get value from registry
  626.     string file;
  627.     RegistryGetString(REG_CONFIG_SECTION, REG_FAVORITES_NAME, &file);
  628.     // if not set, ask user for a folder, then set in registry
  629.     if (file == NO_FAVORITES_FILE) {
  630.         file = wxFileSelector("Select a file for favorites:",
  631.             GetPrefsDir().c_str(), "Favorites", "", "*.*",
  632.             forRead ? wxOPEN : wxSAVE | wxOVERWRITE_PROMPT).c_str();
  633.         if (file.size() > 0)
  634.             if (!RegistrySetString(REG_CONFIG_SECTION, REG_FAVORITES_NAME, file))
  635.                 ERRORMSG("Error setting favorites file in registry");
  636.     }
  637.     return file;
  638. }
  639. static bool LoadFavorites(void)
  640. {
  641.     string favoritesFile;
  642.     RegistryGetString(REG_CONFIG_SECTION, REG_FAVORITES_NAME, &favoritesFile);
  643.     if (favoritesFile != NO_FAVORITES_FILE) {
  644.         favoriteStyles.Reset();
  645.         if (wxFile::Exists(favoritesFile.c_str())) {
  646.             INFOMSG("loading favorites from " << favoritesFile);
  647.             string err;
  648.             if (ReadASNFromFile(favoritesFile.c_str(), &favoriteStyles, false, &err)) {
  649.                 favoriteStylesChanged = false;
  650.                 return true;
  651.             }
  652.         } else {
  653.             WARNINGMSG("Favorites file does not exist: " << favoritesFile);
  654.             RegistrySetString(REG_CONFIG_SECTION, REG_FAVORITES_NAME, NO_FAVORITES_FILE);
  655.         }
  656.     }
  657.     return false;
  658. }
  659. static void SaveFavorites(void)
  660. {
  661.     if (favoriteStylesChanged) {
  662.         int choice = wxMessageBox("Do you want to save changes to your current Favorites file?",
  663.             "Save favorites?", wxYES_NO);
  664.         if (choice == wxYES) {
  665.             string favoritesFile = GetFavoritesFile(false);
  666.             if (favoritesFile != NO_FAVORITES_FILE) {
  667.                 string err;
  668.                 if (!WriteASNToFile(favoritesFile.c_str(), favoriteStyles, false, &err))
  669.                     ERRORMSG("Error saving Favorites to " << favoritesFile << 'n' << err);
  670.                 favoriteStylesChanged = false;
  671.             }
  672.         }
  673.     }
  674. }
  675. void StructureWindow::OnEditFavorite(wxCommandEvent& event)
  676. {
  677.     if (!glCanvas->structureSet) return;
  678.     if (event.GetId() == MID_ADD_FAVORITE) {
  679.         // get name from user
  680.         wxString name = wxGetTextFromUser("Enter a name for this style:", "Input name", "", this);
  681.         if (name.size() == 0) return;
  682.         // replace style of same name
  683.         CCn3d_style_settings *settings;
  684.         CCn3d_style_settings_set::Tdata::iterator f, fe = favoriteStyles.Set().end();
  685.         for (f=favoriteStyles.Set().begin(); f!=fe; ++f) {
  686.             if (Stricmp((*f)->GetName().c_str(), name.c_str()) == 0) {
  687.                 settings = f->GetPointer();
  688.                 break;
  689.             }
  690.         }
  691.         // else add style to list
  692.         if (f == favoriteStyles.Set().end()) {
  693.             if (favoriteStyles.Set().size() >= MID_FAVORITES_END - MID_FAVORITES_BEGIN + 1) {
  694.                 ERRORMSG("Already have max # Favorites");
  695.                 return;
  696.             } else {
  697.                 CRef < CCn3d_style_settings > ref(settings = new CCn3d_style_settings());
  698.                 favoriteStyles.Set().push_back(ref);
  699.             }
  700.         }
  701.         // put in data from global style
  702.         if (!glCanvas->structureSet->styleManager->GetGlobalStyle().SaveSettingsToASN(settings))
  703.             ERRORMSG("Error converting global style to asn");
  704.         settings->SetName(name.c_str());
  705.         favoriteStylesChanged = true;
  706.     }
  707.     else if (event.GetId() == MID_REMOVE_FAVORITE) {
  708.         wxString *choices = new wxString[favoriteStyles.Get().size()];
  709.         int i = 0;
  710.         CCn3d_style_settings_set::Tdata::iterator f, fe = favoriteStyles.Set().end();
  711.         for (f=favoriteStyles.Set().begin(); f!=fe; ++f)
  712.             choices[i++] = (*f)->GetName().c_str();
  713.         int picked = wxGetSingleChoiceIndex("Choose a style to remove from the Favorites list:",
  714.             "Select for removal", favoriteStyles.Set().size(), choices, this);
  715.         if (picked < 0 || picked >= favoriteStyles.Set().size()) return;
  716.         for (f=favoriteStyles.Set().begin(), i=0; f!=fe; ++f, ++i) {
  717.             if (i == picked) {
  718.                 favoriteStyles.Set().erase(f);
  719.                 favoriteStylesChanged = true;
  720.                 break;
  721.             }
  722.         }
  723.     }
  724.     else if (event.GetId() == MID_FAVORITES_FILE) {
  725.         SaveFavorites();
  726.         favoriteStyles.Reset();
  727.         RegistrySetString(REG_CONFIG_SECTION, REG_FAVORITES_NAME, NO_FAVORITES_FILE);
  728.         string newFavorites = GetFavoritesFile(true);
  729.         if (newFavorites != NO_FAVORITES_FILE && wxFile::Exists(newFavorites.c_str())) {
  730.             if (!LoadFavorites())
  731.                 ERRORMSG("Error loading Favorites from " << newFavorites.c_str());
  732.         }
  733.     }
  734.     // update menu
  735.     SetupFavoritesMenu();
  736. }
  737. void StructureWindow::SetupFavoritesMenu(void)
  738. {
  739.     int i;
  740.     for (i=MID_FAVORITES_BEGIN; i<=MID_FAVORITES_END; ++i) {
  741.         wxMenuItem *item = favoritesMenu->FindItem(i);
  742.         if (item) favoritesMenu->Delete(item);
  743.     }
  744.     CCn3d_style_settings_set::Tdata::const_iterator f, fe = favoriteStyles.Get().end();
  745.     for (f=favoriteStyles.Get().begin(), i=0; f!=fe; ++f, ++i)
  746.         favoritesMenu->Append(MID_FAVORITES_BEGIN + i, (*f)->GetName().c_str());
  747. }
  748. void StructureWindow::OnSelectFavorite(wxCommandEvent& event)
  749. {
  750.     if (!glCanvas->structureSet) return;
  751.     if (event.GetId() >= MID_FAVORITES_BEGIN && event.GetId() <= MID_FAVORITES_END) {
  752.         int index = event.GetId() - MID_FAVORITES_BEGIN;
  753.         CCn3d_style_settings_set::Tdata::const_iterator f, fe = favoriteStyles.Get().end();
  754.         int i = 0;
  755.         for (f=favoriteStyles.Get().begin(); f!=fe; ++f, ++i) {
  756.             if (i == index) {
  757.                 INFOMSG("using favorite: " << (*f)->GetName());
  758.                 glCanvas->structureSet->styleManager->SetGlobalStyle(**f);
  759.                 SetRenderingMenuFlag(0);
  760.                 SetColoringMenuFlag(0);
  761.                 break;
  762.             }
  763.         }
  764.     }
  765. }
  766. void StructureWindow::OnShowWindow(wxCommandEvent& event)
  767. {
  768.     switch (event.GetId()) {
  769.         case MID_SHOW_LOG:
  770.             RaiseLogWindow();
  771.             break;
  772.         case MID_SHOW_SEQ_V:
  773.             if (glCanvas->structureSet) glCanvas->structureSet->alignmentManager->ShowSequenceViewer();
  774.             break;
  775.         case MID_SHOW_LOG_START:
  776.             RegistrySetBoolean(REG_CONFIG_SECTION, REG_SHOW_LOG_ON_START,
  777.                 menuBar->IsChecked(MID_SHOW_LOG_START));
  778.             break;
  779.     }
  780. }
  781. void StructureWindow::DialogTextChanged(const MultiTextDialog *changed)
  782. {
  783.     if (!changed || !glCanvas->structureSet) return;
  784.     if (changed == cddNotesDialog) {
  785.         StructureSet::TextLines lines;
  786.         cddNotesDialog->GetLines(&lines);
  787.         if (!glCanvas->structureSet->SetCDDNotes(lines))
  788.             ERRORMSG("Error saving CDD notes");
  789.     }
  790.     if (changed == cddDescriptionDialog) {
  791.         string line;
  792.         cddDescriptionDialog->GetLine(&line);
  793.         if (!glCanvas->structureSet->SetCDDDescription(line))
  794.             ERRORMSG("Error saving CDD description");
  795.     }
  796. }
  797. void StructureWindow::DialogDestroyed(const MultiTextDialog *destroyed)
  798. {
  799.     TRACEMSG("MultiTextDialog destroyed");
  800.     if (destroyed == cddNotesDialog) cddNotesDialog = NULL;
  801.     if (destroyed == cddDescriptionDialog) cddDescriptionDialog = NULL;
  802. }
  803. void StructureWindow::DestroyNonModalDialogs(void)
  804. {
  805.     if (cddAnnotateDialog) cddAnnotateDialog->Destroy();
  806.     if (cddNotesDialog) cddNotesDialog->DestroyDialog();
  807.     if (cddDescriptionDialog) cddDescriptionDialog->DestroyDialog();
  808.     if (cddRefDialog) cddRefDialog->Destroy();
  809.     if (cddBookRefDialog) cddBookRefDialog->Destroy();
  810.     if (cddOverview) cddOverview->Destroy();
  811. }
  812. void StructureWindow::OnPreferences(wxCommandEvent& event)
  813. {
  814.     PreferencesDialog dialog(this);
  815.     int result = dialog.ShowModal();
  816.     glCanvas->Refresh(true); // in case stereo options changed
  817. }
  818. bool StructureWindow::SaveDialog(bool prompt, bool canCancel)
  819. {
  820.     // check for whether save is necessary
  821.     if (!glCanvas->structureSet || !glCanvas->structureSet->HasDataChanged())
  822.         return true;
  823.     int option = wxID_YES;
  824.     if (prompt) {
  825.         option = wxYES_NO | wxYES_DEFAULT | wxICON_EXCLAMATION | wxCENTRE;
  826.         if (canCancel) option |= wxCANCEL;
  827.         wxMessageDialog dialog(NULL, "Do you want to save your work to a file?", "", option);
  828.         option = dialog.ShowModal();
  829.         if (option == wxID_CANCEL) return false; // user cancelled this operation
  830.     }
  831.     if (option == wxID_YES) {
  832.         wxCommandEvent event;
  833.         event.SetId(prompt ? MID_SAVE_AS : MID_SAVE_SAME);
  834.         OnSave(event);    // save data
  835.     }
  836.     return true;
  837. }
  838. // for sorting sequence list in reject dialog
  839. typedef pair < const Sequence * , wxString > SeqAndDescr;
  840. typedef vector < SeqAndDescr > SeqAndDescrList;
  841. static bool CompareSequencesByIdentifier(const SeqAndDescr& a, const SeqAndDescr& b)
  842. {
  843.     return MoleculeIdentifier::CompareIdentifiers(
  844.         a.first->identifier, b.first->identifier);
  845. }
  846. void StructureWindow::ShowCDDOverview(void)
  847. {
  848.     if (!cddOverview)
  849.         cddOverview = new CDDSplashDialog(
  850.             this, glCanvas->structureSet, &cddOverview,
  851.             this, -1, "CDD Descriptive Items", wxPoint(200,50));
  852.     cddOverview->Raise();
  853.     cddOverview->Show(true);
  854. }
  855. void StructureWindow::ShowCDDAnnotations(void)
  856. {
  857.     if (!cddAnnotateDialog)
  858.         cddAnnotateDialog = new CDDAnnotateDialog(this, &cddAnnotateDialog, glCanvas->structureSet);
  859.     cddAnnotateDialog->Raise();
  860.     cddAnnotateDialog->Show(true);
  861. }
  862. void StructureWindow::ShowCDDReferences(void)
  863. {
  864.     if (!cddRefDialog)
  865.         cddRefDialog = new CDDRefDialog(
  866.             glCanvas->structureSet, &cddRefDialog, this, -1, "CDD PubMed References");
  867.     cddRefDialog->Raise();
  868.     cddRefDialog->Show(true);
  869. }
  870. void StructureWindow::ShowCDDBookReferences(void)
  871. {
  872.     if (!cddBookRefDialog)
  873.         cddBookRefDialog = new CDDBookRefDialog(
  874.             glCanvas->structureSet, &cddBookRefDialog, this, -1, "CDD Book References");
  875.     cddBookRefDialog->Raise();
  876.     cddBookRefDialog->Show(true);
  877. }
  878. void StructureWindow::OnCDD(wxCommandEvent& event)
  879. {
  880.     if (!glCanvas->structureSet || !glCanvas->structureSet->IsCDD()) return;
  881.     switch (event.GetId()) {
  882.         case MID_CDD_OVERVIEW:
  883.             ShowCDDOverview();
  884.             break;
  885.         case MID_EDIT_CDD_NAME: {
  886.             wxString newName = wxGetTextFromUser("Enter or edit the CDD name:",
  887.                 "CDD Name", glCanvas->structureSet->GetCDDName().c_str(), this, -1, -1, false);
  888.             if (newName.size() > 0) {
  889.                 if (!glCanvas->structureSet->SetCDDName(newName.c_str()))
  890.                     ERRORMSG("Error saving CDD name");
  891.                 SetWorkingTitle(glCanvas->structureSet);
  892.                 GlobalMessenger()->SetAllWindowTitles();
  893.             }
  894.             break;
  895.         }
  896.         case MID_EDIT_CDD_DESCR:
  897.             if (!cddDescriptionDialog) {
  898.                 StructureSet::TextLines line(1);
  899.                 line[0] = glCanvas->structureSet->GetCDDDescription().c_str();
  900.                 cddDescriptionDialog = new MultiTextDialog(this, line,
  901.                     this, -1, "CDD Description", wxPoint(50, 50), wxSize(400, 200));
  902.             }
  903.             cddDescriptionDialog->ShowDialog(true);
  904.             break;
  905.         case MID_EDIT_CDD_NOTES:
  906.             if (!cddNotesDialog) {
  907.                 StructureSet::TextLines lines;
  908.                 if (!glCanvas->structureSet->GetCDDNotes(&lines)) break;
  909.                 cddNotesDialog = new MultiTextDialog(this, lines,
  910.                     this, -1, "CDD Notes", wxPoint(100, 100), wxSize(500, 400));
  911.             }
  912.             cddNotesDialog->ShowDialog(true);
  913.             break;
  914.         case MID_EDIT_CDD_REFERENCES:
  915.             ShowCDDReferences();
  916.             break;
  917.         case MID_EDIT_CDD_BOOK_REFERENCES:
  918.             ShowCDDBookReferences();
  919.             break;
  920.         case MID_ANNOT_CDD:
  921.             ShowCDDAnnotations();
  922.             break;
  923.         case MID_CDD_SHOW_REJECTS:
  924.             glCanvas->structureSet->ShowRejects();
  925.             break;
  926.         case MID_CDD_REJECT_SEQ: {
  927.             // make a list of slave sequences
  928.             SeqAndDescrList seqsDescrs;
  929.             const MoleculeIdentifier *master =
  930.                 glCanvas->structureSet->alignmentManager->
  931.                     GetCurrentMultipleAlignment()->GetSequenceOfRow(0)->identifier;
  932.             const StructureSet::RejectList *rejects = glCanvas->structureSet->GetRejects();
  933.             SequenceSet::SequenceList::const_iterator
  934.                 s, se = glCanvas->structureSet->sequenceSet->sequences.end();
  935.             for (s=glCanvas->structureSet->sequenceSet->sequences.begin(); s!=se; ++s) {
  936.                 if ((*s)->identifier != master) {
  937.                     // make sure this sequence isn't already rejected
  938.                     bool rejected = false;
  939.                     if (rejects) {
  940.                         StructureSet::RejectList::const_iterator r, re = rejects->end();
  941.                         for (r=rejects->begin(); r!=re; ++r) {
  942.                             CReject_id::TIds::const_iterator i, ie = (*r)->GetIds().end();
  943.                             for (i=(*r)->GetIds().begin(); i!=ie; ++i) {
  944.                                 if ((*s)->identifier->MatchesSeqId(**i)) {
  945.                                     rejected = true;
  946.                                     break;
  947.                                 }
  948.                             }
  949.                             if (rejected) break;
  950.                         }
  951.                     }
  952.                     if (rejected) continue;
  953.                     wxString description((*s)->identifier->ToString().c_str());
  954.                     if ((*s)->description.size() > 0)
  955.                         description += wxString("     ") + (*s)->description.c_str();
  956.                     seqsDescrs.resize(seqsDescrs.size() + 1);
  957.                     seqsDescrs.back().first = *s;
  958.                     seqsDescrs.back().second = description;
  959.                 }
  960.             }
  961.             // sort by identifier
  962.             stable_sort(seqsDescrs.begin(), seqsDescrs.end(), CompareSequencesByIdentifier);
  963.             // user dialogs for selection and reason
  964.             wxString *choices = new wxString[seqsDescrs.size()];
  965.             int choice;
  966.             for (choice=0; choice<seqsDescrs.size(); ++choice) choices[choice] = seqsDescrs[choice].second;
  967.             choice = wxGetSingleChoiceIndex("Reject which sequence?", "Reject Sequence",
  968.                 seqsDescrs.size(), choices, this);
  969.             if (choice >= 0) {
  970.                 wxString message = "Are you sure you want to reject this sequence?nn";
  971.                 message += choices[choice];
  972.                 message += "nnIf so, enter a brief reason why:";
  973.                 wxString reason = wxGetTextFromUser(message, "Reject Sequence", "", this);
  974.                 if (reason.size() == 0) {
  975.                     wxMessageBox("Reject action cancelled!", "", wxOK | wxICON_INFORMATION, this);
  976.                 } else {
  977.                     int purge = wxMessageBox("Do you want to purge all instances of this sequence "
  978.                         " from the multiple alignment and update list?",
  979.                         "", wxYES_NO | wxICON_QUESTION, this);
  980.                     // finally, actually perform the rejection+purge
  981.                     glCanvas->structureSet->
  982.                         RejectAndPurgeSequence(seqsDescrs[choice].first, reason.c_str(), purge == wxYES);
  983.                 }
  984.             }
  985.             break;
  986.         }
  987.     }
  988. }
  989. void StructureWindow::OnAdjustView(wxCommandEvent& event)
  990. {
  991.     glCanvas->SetCurrent();
  992.     switch (event.GetId()) {
  993.         case MID_ZOOM_IN:       glCanvas->renderer->ChangeView(OpenGLRenderer::eZoomIn); break;
  994.         case MID_ZOOM_OUT:      glCanvas->renderer->ChangeView(OpenGLRenderer::eZoomOut); break;
  995.         case MID_RESET:         glCanvas->renderer->ResetCamera(); break;
  996.         case MID_RESTORE:       glCanvas->renderer->RestoreSavedView(); break;
  997.         case MID_FIRST_FRAME:   glCanvas->renderer->ShowFirstFrame(); break;
  998.         case MID_LAST_FRAME:    glCanvas->renderer->ShowLastFrame(); break;
  999.         case MID_NEXT_FRAME:    glCanvas->renderer->ShowNextFrame(); break;
  1000.         case MID_PREV_FRAME:    glCanvas->renderer->ShowPreviousFrame(); break;
  1001.         case MID_ALL_FRAMES:    glCanvas->renderer->ShowAllFrames(); break;
  1002.         case MID_STEREO:        glCanvas->renderer->EnableStereo(menuBar->IsChecked(MID_STEREO)); break;
  1003.         default:
  1004.             break;
  1005.     }
  1006.     glCanvas->Refresh(false);
  1007. }
  1008. void StructureWindow::OnShowHide(wxCommandEvent& event)
  1009. {
  1010.     if (glCanvas->structureSet) {
  1011.         switch (event.GetId()) {
  1012.         case MID_SHOW_HIDE:
  1013.         {
  1014.             vector < string > structureNames;
  1015.             vector < bool > structureVisibilities;
  1016.             glCanvas->structureSet->showHideManager->GetShowHideInfo(&structureNames, &structureVisibilities);
  1017.             wxString *titles = new wxString[structureNames.size()];
  1018.             for (int i=0; i<structureNames.size(); ++i) titles[i] = structureNames[i].c_str();
  1019.             ShowHideDialog dialog(
  1020.                 titles, &structureVisibilities, glCanvas->structureSet->showHideManager, false,
  1021.                 this, -1, "Show/Hide Structures", wxPoint(200, 50));
  1022.             dialog.ShowModal();
  1023.             //delete titles;    // apparently deleted by wxWindows
  1024.             break;
  1025.         }
  1026.         case MID_SELECT_MOLECULE:
  1027.         {
  1028.             if (!glCanvas->structureSet || glCanvas->structureSet->objects.size() > 1)
  1029.                 return;
  1030.             wxString idStr = wxGetTextFromUser("Enter an MMDB molecule ID or PDB code:", "Select molecule");
  1031.             if (idStr.size() == 0)
  1032.                 return;
  1033.             unsigned long num;
  1034.             bool isNum = idStr.ToULong(&num);
  1035.             if (!isNum)
  1036.                 idStr.MakeUpper();  // PDB names are all caps
  1037.             GlobalMessenger()->RemoveAllHighlights(true);
  1038.             ChemicalGraph::MoleculeMap::const_iterator m, me =
  1039.                 glCanvas->structureSet->objects.front()->graph->molecules.end();
  1040.             for (m=glCanvas->structureSet->objects.front()->graph->molecules.begin(); m!=me; ++m) {
  1041.                 if ((isNum && m->second->id == (int) num) ||
  1042.                     (!isNum && (
  1043.                         ((m->second->type == Molecule::eDNA || m->second->type == Molecule::eRNA ||
  1044.                           m->second->type == Molecule::eProtein || m->second->type == Molecule::eBiopolymer)
  1045.                             && idStr.Cmp(m->second->name.c_str()) == 0) ||
  1046.                         ((m->second->type == Molecule::eSolvent || m->second->type == Molecule::eNonpolymer ||
  1047.                           m->second->type == Molecule::eOther)
  1048.                             && m->second->residues.size() == 1
  1049.                             && (((wxString) m->second->residues.begin()->second->
  1050.                                 nameGraph.c_str()).Strip(wxString::both) == idStr)))))
  1051.                 {
  1052.                     if (m->second->sequence) {
  1053.                         GlobalMessenger()->AddHighlights(m->second->sequence, 0, m->second->sequence->Length() - 1);
  1054.                     } else {
  1055.                         Molecule::ResidueMap::const_iterator r, re = m->second->residues.end();
  1056.                         for (r=m->second->residues.begin(); r!=re; ++r)
  1057.                             GlobalMessenger()->ToggleHighlight(m->second, r->second->id);
  1058.                     }
  1059.                 }
  1060.             }
  1061.             break;
  1062.         }
  1063.         case MID_SHOW_ALL:
  1064.             glCanvas->structureSet->showHideManager->MakeAllVisible();
  1065.             break;
  1066.         case MID_SHOW_DOMAINS:
  1067.             glCanvas->structureSet->showHideManager->ShowAlignedDomains(glCanvas->structureSet);
  1068.             break;
  1069.         case MID_SHOW_ALIGNED:
  1070.             glCanvas->structureSet->showHideManager->ShowResidues(glCanvas->structureSet, true);
  1071.             break;
  1072.         case MID_SHOW_UNALIGNED_ALL:
  1073.             glCanvas->structureSet->showHideManager->ShowResidues(glCanvas->structureSet, false);
  1074.             break;
  1075.         case MID_SHOW_UNALIGNED_ALN_DOMAIN:
  1076.             glCanvas->structureSet->showHideManager->
  1077.                 ShowUnalignedResiduesInAlignedDomains(glCanvas->structureSet);
  1078.             break;
  1079.         case MID_SHOW_SELECTED_RESIDUES:
  1080.             glCanvas->structureSet->showHideManager->ShowSelectedResidues(glCanvas->structureSet);
  1081.             break;
  1082.         case MID_SHOW_SELECTED_DOMAINS:
  1083.             glCanvas->structureSet->showHideManager->ShowDomainsWithHighlights(glCanvas->structureSet);
  1084.             break;
  1085.         }
  1086.     }
  1087. }
  1088. void StructureWindow::OnAlignStructures(wxCommandEvent& event)
  1089. {
  1090.     if (glCanvas->structureSet) {
  1091.         glCanvas->structureSet->alignmentManager->RealignAllSlaveStructures();
  1092.         glCanvas->SetCurrent();
  1093.         glCanvas->Refresh(false);
  1094.     }
  1095. }
  1096. #define RENDERING_SHORTCUT(type, menu) 
  1097.     glCanvas->structureSet->styleManager->SetGlobalRenderingStyle(StyleSettings::type); 
  1098.     SetRenderingMenuFlag(menu); 
  1099.     break
  1100. #define COLORING_SHORTCUT(type, menu) 
  1101.     glCanvas->structureSet->styleManager->SetGlobalColorScheme(StyleSettings::type); 
  1102.     SetColoringMenuFlag(menu); 
  1103.     break
  1104. void StructureWindow::OnSetStyle(wxCommandEvent& event)
  1105. {
  1106.     if (glCanvas->structureSet) {
  1107.         glCanvas->SetCurrent();
  1108.         switch (event.GetId()) {
  1109.             case MID_EDIT_STYLE:
  1110.                 if (!glCanvas->structureSet->styleManager->EditGlobalStyle(this))
  1111.                     return;
  1112.                 SetRenderingMenuFlag(0);
  1113.                 SetColoringMenuFlag(0);
  1114.                 break;
  1115.             case MID_ANNOTATE:
  1116.                 if (!glCanvas->structureSet->styleManager->EditUserAnnotations(this))
  1117.                     return;
  1118.                 break;
  1119.             case MID_WORM: RENDERING_SHORTCUT(eWormShortcut, MID_WORM);
  1120.             case MID_TUBE: RENDERING_SHORTCUT(eTubeShortcut, MID_TUBE);
  1121.             case MID_WIRE: RENDERING_SHORTCUT(eWireframeShortcut, MID_WIRE);
  1122.             case MID_BNS: RENDERING_SHORTCUT(eBallAndStickShortcut, MID_BNS);
  1123.             case MID_SPACE: RENDERING_SHORTCUT(eSpacefillShortcut, MID_SPACE);
  1124.             case MID_SC_TOGGLE: RENDERING_SHORTCUT(eToggleSidechainsShortcut, 0);
  1125.             case MID_SECSTRUC: COLORING_SHORTCUT(eSecondaryStructureShortcut, MID_SECSTRUC);
  1126.             case MID_ALIGNED: COLORING_SHORTCUT(eAlignedShortcut, MID_ALIGNED);
  1127.             case MID_IDENTITY: COLORING_SHORTCUT(eIdentityShortcut, MID_IDENTITY);
  1128.             case MID_VARIETY: COLORING_SHORTCUT(eVarietyShortcut, MID_VARIETY);
  1129.             case MID_WGHT_VAR: COLORING_SHORTCUT(eWeightedVarietyShortcut, MID_WGHT_VAR);
  1130.             case MID_INFO: COLORING_SHORTCUT(eInformationContentShortcut, MID_INFO);
  1131.             case MID_FIT: COLORING_SHORTCUT(eFitShortcut, MID_FIT);
  1132.             case MID_BLOCK_FIT: COLORING_SHORTCUT(eBlockFitShortcut, MID_BLOCK_FIT);
  1133.             case MID_BLOCK_Z_FIT: COLORING_SHORTCUT(eBlockZFitShortcut, MID_BLOCK_Z_FIT);
  1134.             case MID_BLOCK_ROW_FIT: COLORING_SHORTCUT(eBlockRowFitShortcut, MID_BLOCK_ROW_FIT);
  1135.             case MID_OBJECT: COLORING_SHORTCUT(eObjectShortcut, MID_OBJECT);
  1136.             case MID_DOMAIN: COLORING_SHORTCUT(eDomainShortcut, MID_DOMAIN);
  1137.             case MID_MOLECULE: COLORING_SHORTCUT(eMoleculeShortcut, MID_MOLECULE);
  1138.             case MID_RAINBOW: COLORING_SHORTCUT(eRainbowShortcut, MID_RAINBOW);
  1139.             case MID_HYDROPHOB: COLORING_SHORTCUT(eHydrophobicityShortcut, MID_HYDROPHOB);
  1140.             case MID_CHARGE: COLORING_SHORTCUT(eChargeShortcut, MID_CHARGE);
  1141.             case MID_TEMP: COLORING_SHORTCUT(eTemperatureShortcut, MID_TEMP);
  1142.             case MID_ELEMENT: COLORING_SHORTCUT(eElementShortcut, MID_ELEMENT);
  1143.             default:
  1144.                 return;
  1145.         }
  1146.         glCanvas->structureSet->styleManager->CheckGlobalStyleSettings();
  1147.         GlobalMessenger()->PostRedrawAllStructures();
  1148.         GlobalMessenger()->PostRedrawAllSequenceViewers();
  1149.     }
  1150. }
  1151. void StructureWindow::SetRenderingMenuFlag(int which)
  1152. {
  1153.     menuBar->Check(MID_WORM, (which == MID_WORM));
  1154.     menuBar->Check(MID_TUBE, (which == MID_TUBE));
  1155.     menuBar->Check(MID_WIRE, (which == MID_WIRE));
  1156.     menuBar->Check(MID_BNS, (which == MID_BNS));
  1157.     menuBar->Check(MID_SPACE, (which == MID_SPACE));
  1158. }
  1159. void StructureWindow::SetColoringMenuFlag(int which)
  1160. {
  1161.     menuBar->Check(MID_SECSTRUC, (which == MID_SECSTRUC));
  1162.     menuBar->Check(MID_ALIGNED, (which == MID_ALIGNED));
  1163.     menuBar->Check(MID_IDENTITY, (which == MID_IDENTITY));
  1164.     menuBar->Check(MID_VARIETY, (which == MID_VARIETY));
  1165.     menuBar->Check(MID_WGHT_VAR, (which == MID_WGHT_VAR));
  1166.     menuBar->Check(MID_INFO, (which == MID_INFO));
  1167.     menuBar->Check(MID_FIT, (which == MID_FIT));
  1168.     menuBar->Check(MID_BLOCK_FIT, (which == MID_BLOCK_FIT));
  1169.     menuBar->Check(MID_BLOCK_Z_FIT, (which == MID_BLOCK_Z_FIT));
  1170.     menuBar->Check(MID_BLOCK_ROW_FIT, (which == MID_BLOCK_ROW_FIT));
  1171.     menuBar->Check(MID_OBJECT, (which == MID_OBJECT));
  1172.     menuBar->Check(MID_DOMAIN, (which == MID_DOMAIN));
  1173.     menuBar->Check(MID_MOLECULE, (which == MID_MOLECULE));
  1174.     menuBar->Check(MID_RAINBOW, (which == MID_RAINBOW));
  1175.     menuBar->Check(MID_HYDROPHOB, (which == MID_HYDROPHOB));
  1176.     menuBar->Check(MID_CHARGE, (which == MID_CHARGE));
  1177.     menuBar->Check(MID_TEMP, (which == MID_TEMP));
  1178.     menuBar->Check(MID_ELEMENT, (which == MID_ELEMENT));
  1179. }
  1180. bool StructureWindow::LoadData(const char *filename, bool force, CNcbi_mime_asn1 *mimeData)
  1181. {
  1182.     SetCursor(*wxHOURGLASS_CURSOR);
  1183.     glCanvas->SetCurrent();
  1184.     if (force) {
  1185.         fileMenu->Enable(MID_OPEN, false);
  1186.         fileMenu->Enable(MID_SAVE_AS, false);
  1187.     }
  1188.     // clear old data
  1189.     if (glCanvas->structureSet) {
  1190.         DestroyNonModalDialogs();
  1191.         GlobalMessenger()->RemoveAllHighlights(false);
  1192.         delete glCanvas->structureSet;
  1193.         glCanvas->structureSet = NULL;
  1194.         glCanvas->renderer->AttachStructureSet(NULL);
  1195.         glCanvas->Refresh(false);
  1196.     }
  1197.     // get current structure limit
  1198.     int structureLimit = kMax_Int;
  1199.     if (!RegistryGetInteger(REG_ADVANCED_SECTION, REG_MAX_N_STRUCTS, &structureLimit))
  1200.         WARNINGMSG("Can't get structure limit from registry");
  1201.     // use passed-in data if present, otherwise load from file
  1202.     if (mimeData) {
  1203.         glCanvas->structureSet = new StructureSet(mimeData, structureLimit, glCanvas->renderer);
  1204.         userDir = GetWorkingDir();
  1205.         currentFile = "";
  1206.     }
  1207.     else {
  1208.         // set up various paths relative to given filename
  1209.         if (wxIsAbsolutePath(filename))
  1210.             userDir = string(wxPathOnly(filename).c_str()) + wxFILE_SEP_PATH;
  1211.         else if (wxPathOnly(filename) == "")
  1212.             userDir = GetWorkingDir();
  1213.         else
  1214.             userDir = GetWorkingDir() + wxPathOnly(filename).c_str() + wxFILE_SEP_PATH;
  1215.         INFOMSG("user dir: " << userDir.c_str());
  1216.         // try to decide if what ASN type this is, and if it's binary or ascii
  1217.         CNcbiIstream *inStream = new CNcbiIfstream(filename, IOS_BASE::in | IOS_BASE::binary);
  1218.         if (!(*inStream)) {
  1219.             ERRORMSG("Cannot open file '" << filename << "' for reading");
  1220.             SetCursor(wxNullCursor);
  1221.             delete inStream;
  1222.             return false;
  1223.         }
  1224.         currentFile = wxFileNameFromPath(filename);
  1225.         string firstWord;
  1226.         *inStream >> firstWord;
  1227.         delete inStream;
  1228.         static const string
  1229.             asciiMimeFirstWord = "Ncbi-mime-asn1",
  1230.             asciiCDDFirstWord = "Cdd";
  1231.         bool isMime = false, isCDD = false, isBinary = true;
  1232.         if (firstWord == asciiMimeFirstWord) {
  1233.             isMime = true;
  1234.             isBinary = false;
  1235.         } else if (firstWord == asciiCDDFirstWord) {
  1236.             isCDD = true;
  1237.             isBinary = false;
  1238.         }
  1239.         // try to read the file as various ASN types (if it's not clear from the first ascii word).
  1240.         // If read is successful, the StructureSet will own the asn data object, to keep it
  1241.         // around for output later on
  1242.         bool readOK = false;
  1243.         string err;
  1244.         if (!isCDD) {
  1245.             TRACEMSG("trying to read file '" << filename << "' as " <<
  1246.                 ((isBinary) ? "binary" : "ascii") << " mime");
  1247.             CNcbi_mime_asn1 *mime = new CNcbi_mime_asn1();
  1248.             SetDiagPostLevel(eDiag_Fatal); // ignore all but Fatal errors while reading data
  1249.             readOK = ReadASNFromFile(filename, mime, isBinary, &err);
  1250.             SetDiagPostLevel(eDiag_Info);
  1251.             if (readOK) {
  1252.                 glCanvas->structureSet = new StructureSet(mime, structureLimit, glCanvas->renderer);
  1253.                 // if CDD is contained in a mime, then show CDD splash screen
  1254.                 if (glCanvas->structureSet->IsCDD())
  1255.                     ShowCDDOverview();
  1256.             } else {
  1257.                 TRACEMSG("error: " << err);
  1258.                 delete mime;
  1259.             }
  1260.         }
  1261.         if (!readOK) {
  1262.             TRACEMSG("trying to read file '" << filename << "' as " <<
  1263.                 ((isBinary) ? "binary" : "ascii") << " cdd");
  1264.             CCdd *cdd = new CCdd();
  1265.             SetDiagPostLevel(eDiag_Fatal); // ignore all but Fatal errors while reading data
  1266.             readOK = ReadASNFromFile(filename, cdd, isBinary, &err);
  1267.             SetDiagPostLevel(eDiag_Info);
  1268.             if (readOK) {
  1269.                 glCanvas->structureSet = new StructureSet(cdd, structureLimit, glCanvas->renderer);
  1270.             } else {
  1271.                 TRACEMSG("error: " << err);
  1272.                 delete cdd;
  1273.             }
  1274.         }
  1275.         if (!readOK) {
  1276.             ERRORMSG("File not found, not readable, or is not a recognized data type");
  1277.             SetCursor(wxNullCursor);
  1278.             return false;
  1279.         }
  1280.     }
  1281.     SetWorkingTitle(glCanvas->structureSet);
  1282.     GlobalMessenger()->SetAllWindowTitles();
  1283.     // use a default style if no global style stored in asn data
  1284.     if (glCanvas->structureSet->hasUserStyle) {
  1285.         SetRenderingMenuFlag(0);
  1286.         SetColoringMenuFlag(0);
  1287.     } else {
  1288.         // set default rendering style and view, and turn on corresponding style menu flags
  1289.         if (glCanvas->structureSet->alignmentSet) {
  1290.             glCanvas->structureSet->styleManager->SetGlobalRenderingStyle(StyleSettings::eTubeShortcut);
  1291.             SetRenderingMenuFlag(MID_TUBE);
  1292.             if (glCanvas->structureSet->IsCDD()) {
  1293.                 glCanvas->structureSet->styleManager->SetGlobalColorScheme(StyleSettings::eInformationContentShortcut);
  1294.                 SetColoringMenuFlag(MID_INFO);
  1295.             } else {
  1296.                 glCanvas->structureSet->styleManager->SetGlobalColorScheme(StyleSettings::eIdentityShortcut);
  1297.                 SetColoringMenuFlag(MID_IDENTITY);
  1298.             }
  1299.         } else {
  1300.             glCanvas->structureSet->styleManager->SetGlobalRenderingStyle(StyleSettings::eWormShortcut);
  1301.             SetRenderingMenuFlag(MID_WORM);
  1302.             glCanvas->structureSet->styleManager->SetGlobalColorScheme(StyleSettings::eSecondaryStructureShortcut);
  1303.             SetColoringMenuFlag(MID_SECSTRUC);
  1304.         }
  1305.     }
  1306.     menuBar->EnableTop(menuBar->FindMenu("CDD"), glCanvas->structureSet->IsCDD());
  1307.     glCanvas->renderer->AttachStructureSet(glCanvas->structureSet);
  1308.     if (!glCanvas->renderer->HasASNViewSettings())
  1309.         glCanvas->structureSet->CenterViewOnAlignedResidues();
  1310.     glCanvas->Refresh(false);
  1311.     glCanvas->structureSet->alignmentManager->ShowSequenceViewer();
  1312.     SetCursor(wxNullCursor);
  1313.     return true;
  1314. }
  1315. void StructureWindow::OnOpen(wxCommandEvent& event)
  1316. {
  1317.     if (glCanvas->structureSet) {
  1318.         GlobalMessenger()->SequenceWindowsSave(true);   // give sequence window a chance to save
  1319.         SaveDialog(true, false);                        // give structure window a chance to save data
  1320.     }
  1321.     if (event.GetId() == MID_OPEN) {
  1322.         const wxString& filestr = wxFileSelector("Choose a text or binary ASN1 file to open", userDir.c_str(),
  1323.             "", "", "All Files|*.*|CDD (*.acd)|*.acd|Binary ASN (*.val)|*.val|ASCII ASN (*.prt)|*.prt",
  1324.             wxOPEN | wxFILE_MUST_EXIST);
  1325.         if (!filestr.IsEmpty())
  1326.             LoadData(filestr.c_str(), false);
  1327.     }
  1328.     else if (event.GetId() == MID_NETWORK_OPEN) {
  1329.         wxString id = wxGetTextFromUser("Please enter a PDB or MMDB id", "Input id");
  1330.         if (id.size() == 0)
  1331.             return;
  1332.         wxArrayString choiceStrs;
  1333.         choiceStrs.Add("single");
  1334.         choiceStrs.Add("alpha");
  1335.         choiceStrs.Add("PDB");
  1336.         wxString modelStr = wxGetSingleChoice(
  1337.             "Please select which type of model you'd like to load", "Select model", choiceStrs);
  1338.         if (modelStr.size() == 0)
  1339.             return;
  1340.         EModel_type model = eModel_type_ncbi_all_atom;
  1341.         if (modelStr == "alpha")
  1342.             model = eModel_type_ncbi_backbone;
  1343.         else if (modelStr == "PDB")
  1344.             model = eModel_type_pdb_model;
  1345.         CNcbi_mime_asn1 *mime = LoadStructureViaCache(id.c_str(), model);
  1346.         if (mime)
  1347.             LoadData(NULL, false, mime);
  1348.     }
  1349. }
  1350. void StructureWindow::OnSave(wxCommandEvent& event)
  1351. {
  1352.     if (!glCanvas->structureSet) return;
  1353.     // determine whether to prompt user for filename
  1354.     bool prompt = (event.GetId() == MID_SAVE_AS);
  1355.     if (!prompt) {
  1356.         wxString dir = wxString(userDir.c_str()).MakeLower();
  1357.         // always prompt if this file is stored in some temp folder (e.g. browser cache)
  1358.         if (dir.Contains("cache") || dir.Contains("temp") || dir.Contains("tmp"))
  1359.             prompt = true;
  1360.     }
  1361.     // force a save of any edits to alignment and updates first
  1362.     GlobalMessenger()->SequenceWindowsSave(prompt);
  1363.     wxString outputFolder = wxString(userDir.c_str(), userDir.size() - 1); // remove trailing /
  1364.     wxString outputFilename;
  1365.     bool outputBinary;
  1366.     // don't ask for filename if Save As is disabled
  1367.     if ((prompt && fileMenu->IsEnabled(MID_SAVE_AS)) || currentFile.size() == 0) {
  1368.         wxFileName fn(currentFile.c_str());
  1369.         wxFileDialog dialog(this, "Choose a filename for output", outputFolder,
  1370. #ifdef __WXGTK__
  1371.             fn.GetFullName(),
  1372. #else
  1373.             fn.GetName(),
  1374. #endif
  1375.             "All Files|*.*|Binary ASN (*.val)|*.val|ASCII CDD (*.acd)|*.acd|ASCII ASN (*.prt)|*.prt",
  1376.             wxSAVE | wxOVERWRITE_PROMPT);
  1377.         dialog.SetFilterIndex(fn.GetExt() == "val" ? 1 : (fn.GetExt() == "acd" ? 2 :
  1378.             (fn.GetExt() == "prt" ? 3 : 0)));
  1379.         if (dialog.ShowModal() == wxID_OK)
  1380.             outputFilename = dialog.GetPath();
  1381.         outputBinary = (dialog.GetFilterIndex() == 1);
  1382.     } else {
  1383.         outputFilename = (userDir + currentFile).c_str();
  1384.         outputBinary = (outputFilename.Right(4) == ".val");
  1385.     }
  1386.     INFOMSG("save file: '" << outputFilename.c_str() << "'");
  1387.     if (!outputFilename.IsEmpty()) {
  1388.         // convert mime to cdd if specified
  1389.         if (outputFilename.Right(4) == ".acd" &&
  1390.             (!glCanvas->structureSet->IsCDD() || glCanvas->structureSet->IsCDDInMime()))
  1391.         {
  1392.             string cddName;
  1393.             if (glCanvas->structureSet->IsCDDInMime() && glCanvas->structureSet->GetCDDName().size() > 0)
  1394.                 cddName = glCanvas->structureSet->GetCDDName();
  1395.             else
  1396.                 cddName = wxGetTextFromUser("Enter a name for this CD", "Input Name");
  1397.             if (cddName.size() == 0 || !glCanvas->structureSet->ConvertMimeDataToCDD(cddName.c_str())) {
  1398.                 ERRORMSG("Conversion to Cdd failed");
  1399.                 return;
  1400.             }
  1401.         }
  1402.         // save and send FileSaved command
  1403.         unsigned int changeFlags;
  1404.         if (glCanvas->structureSet->SaveASNData(outputFilename.c_str(), outputBinary, &changeFlags) &&
  1405.             IsFileMessengerActive())
  1406.         {
  1407.             string data(outputFilename.c_str());
  1408.             data += 'n';
  1409.             TRACEMSG("changeFlags: " << changeFlags);
  1410.             if ((changeFlags & StructureSet::eAnyAlignmentData) > 0)
  1411.                 data += "AlignmentChangedn";
  1412.             if ((changeFlags & StructureSet::eRowOrderData) > 0)
  1413.                 data += "RowOrderChangedn";
  1414.             if ((changeFlags & StructureSet::ePSSMData) > 0)
  1415.                 data += "PSSMChangedn";
  1416.             if ((changeFlags & StructureSet::eCDDData) > 0)
  1417.                 data += "DescriptionChangedn";
  1418.             if ((changeFlags & StructureSet::eUpdateData) > 0)
  1419.                 data += "PendingAlignmentsChangedn";
  1420.             SendCommand(messageTargetApp, "FileSaved", data);
  1421.         }
  1422. #ifdef __WXMAC__
  1423.         // set mac file type and creator
  1424.         wxFileName wxfn(outputFilename);
  1425.         if (wxfn.FileExists())
  1426.             if (!wxfn.MacSetTypeAndCreator('TEXT', 'Cn3D'))
  1427.                 WARNINGMSG("Unable to set Mac file type/creator");
  1428. #endif
  1429.         // set path/name/title
  1430.         if (wxIsAbsolutePath(outputFilename))
  1431.             userDir = string(wxPathOnly(outputFilename).c_str()) + wxFILE_SEP_PATH;
  1432.         else if (wxPathOnly(outputFilename) == "")
  1433.             userDir = GetWorkingDir();
  1434.         else
  1435.             userDir = GetWorkingDir() + wxPathOnly(outputFilename).c_str() + wxFILE_SEP_PATH;
  1436.         currentFile = wxFileNameFromPath(outputFilename);
  1437.         SetWorkingTitle(glCanvas->structureSet);
  1438.         GlobalMessenger()->SetAllWindowTitles();
  1439.     }
  1440. }
  1441. END_SCOPE(Cn3D)
  1442. /*
  1443. * ---------------------------------------------------------------------------
  1444. * $Log: structure_window.cpp,v $
  1445. * Revision 1000.3  2004/06/01 18:29:33  gouriano
  1446. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.33
  1447. *
  1448. * Revision 1.33  2004/05/31 13:15:09  thiessen
  1449. * make select molecule take PDB chain/het name
  1450. *
  1451. * Revision 1.32  2004/05/21 21:41:40  gorelenk
  1452. * Added PCH ncbi_pch.hpp
  1453. *
  1454. * Revision 1.31  2004/05/21 17:29:51  thiessen
  1455. * allow conversion of mime to cdd data
  1456. *
  1457. * Revision 1.30  2004/04/22 00:05:03  thiessen
  1458. * add seclect molecule
  1459. *
  1460. * Revision 1.29  2004/03/15 18:38:52  thiessen
  1461. * prefer prefix vs. postfix ++/-- operators
  1462. *
  1463. * Revision 1.28  2004/03/09 14:30:47  thiessen
  1464. * change network load type choice order
  1465. *
  1466. * Revision 1.27  2004/02/19 17:05:16  thiessen
  1467. * remove cn3d/ from include paths; add pragma to disable annoying msvc warning
  1468. *
  1469. * Revision 1.26  2004/01/17 01:47:26  thiessen
  1470. * add network load
  1471. *
  1472. * Revision 1.25  2004/01/17 00:17:31  thiessen
  1473. * add Biostruc and network structure load
  1474. *
  1475. * Revision 1.24  2004/01/08 15:31:03  thiessen
  1476. * remove hard-coded CDTree references in messaging; add Cn3DTerminated message upon exit
  1477. *
  1478. * Revision 1.23  2003/12/03 15:46:36  thiessen
  1479. * adjust so spin increment is accurate
  1480. *
  1481. * Revision 1.22  2003/12/03 15:07:10  thiessen
  1482. * add more sophisticated animation controls
  1483. *
  1484. * Revision 1.21  2003/11/15 16:08:36  thiessen
  1485. * add stereo
  1486. *
  1487. * Revision 1.20  2003/09/26 17:39:14  thiessen
  1488. * fixes for button states
  1489. *
  1490. * Revision 1.19  2003/09/26 17:12:46  thiessen
  1491. * add book reference dialog
  1492. *
  1493. * Revision 1.18  2003/09/22 17:33:12  thiessen
  1494. * add AlignmentChanged flag; flush message file; check row order of repeats
  1495. *
  1496. * Revision 1.17  2003/08/04 15:29:46  thiessen
  1497. * send PendingAlignmentsChanged to CDTree2
  1498. *
  1499. * Revision 1.16  2003/07/17 20:13:52  thiessen
  1500. * don't ask for filename on save/termination with -f; add eAnyAlignmentData flag
  1501. *
  1502. * Revision 1.15  2003/07/17 18:47:01  thiessen
  1503. * add -f option to force save to same file
  1504. *
  1505. * Revision 1.14  2003/07/17 16:52:34  thiessen
  1506. * add FileSaved message with edit typing
  1507. *
  1508. * Revision 1.13  2003/07/14 18:37:08  thiessen
  1509. * change GetUngappedAlignedBlocks() param types; other syntax changes
  1510. *
  1511. * Revision 1.12  2003/07/10 18:47:29  thiessen
  1512. * add CDTree->Select command
  1513. *
  1514. * Revision 1.11  2003/07/10 13:47:22  thiessen
  1515. * add LoadFile command
  1516. *
  1517. * Revision 1.10  2003/05/07 14:02:47  thiessen
  1518. * add accelerators
  1519. *
  1520. * Revision 1.9  2003/05/06 19:10:47  thiessen
  1521. * add show aligned domains key shortcut 'd'
  1522. *
  1523. * Revision 1.8  2003/05/05 22:47:18  thiessen
  1524. * add e = show-everything shortcut
  1525. *
  1526. * Revision 1.7  2003/03/20 20:33:51  thiessen
  1527. * implement Highlight command
  1528. *
  1529. * Revision 1.6  2003/03/14 19:22:59  thiessen
  1530. * add CommandProcessor to handle file-message commands; fixes for GCC 2.9
  1531. *
  1532. * Revision 1.5  2003/03/13 22:55:29  thiessen
  1533. * another Solaris/workshop fix
  1534. *
  1535. * Revision 1.4  2003/03/13 22:48:43  thiessen
  1536. * fixes for Mac/OSX/gcc
  1537. *
  1538. * Revision 1.3  2003/03/13 18:55:17  thiessen
  1539. * tweak file load error reporting
  1540. *
  1541. * Revision 1.2  2003/03/13 16:57:14  thiessen
  1542. * fix favorites load/save problem
  1543. *
  1544. * Revision 1.1  2003/03/13 14:26:18  thiessen
  1545. * add file_messaging module; split cn3d_main_wxwin into cn3d_app, cn3d_glcanvas, structure_window, cn3d_tools
  1546. *
  1547. */