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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: cn3d_app.cpp,v $
  4.  * PRODUCTION Revision 1000.3  2004/06/01 18:28:05  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.21
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: cn3d_app.cpp,v 1000.3 2004/06/01 18:28:05 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. *       log and application 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 <ctools/ctools.h>
  48. #include <serial/objostr.hpp>
  49. #include <objects/mmdb1/Biostruc.hpp>
  50. #include <objects/ncbimime/Ncbi_mime_asn1.hpp>
  51. #include <objects/ncbimime/Biostruc_seq.hpp>
  52. #include <objects/seq/Bioseq.hpp>
  53. #include <objects/seqset/Seq_entry.hpp>
  54. #include <objects/seqset/Bioseq_set.hpp>
  55. #include <objects/mmdb2/Biostruc_model.hpp>
  56. #include <objects/mmdb2/Model_type.hpp>
  57. #include <objects/mmdb1/Biostruc_graph.hpp>
  58. #include <objects/mmdb1/Molecule_graph.hpp>
  59. #include <objects/seqloc/Seq_id.hpp>
  60. #include <algorithm>
  61. #include <vector>
  62. #ifdef __WXMSW__
  63. #include <windows.h>
  64. #include <wx/msw/winundef.h>
  65. #endif
  66. #include <wx/wx.h>
  67. #include <wx/filesys.h>
  68. #include <wx/fs_zip.h>
  69. #include "asn_reader.hpp"
  70. #include "cn3d_app.hpp"
  71. #include "structure_window.hpp"
  72. #include "cn3d_tools.hpp"
  73. #include "structure_set.hpp"
  74. #include "chemical_graph.hpp"
  75. #include "cn3d_glcanvas.hpp"
  76. #include "opengl_renderer.hpp"
  77. #include "messenger.hpp"
  78. #include "alignment_manager.hpp"
  79. #include "cn3d_cache.hpp"
  80. // the application icon (under Windows it is in resources)
  81. #if defined(__WXGTK__) || defined(__WXMAC__)
  82.     #include "cn3d.xpm"
  83. #endif
  84. #include <ncbi.h>
  85. #include <ncbienv.h>
  86. USING_NCBI_SCOPE;
  87. USING_SCOPE(objects);
  88. // `Main program' equivalent
  89. IMPLEMENT_APP(Cn3D::Cn3DApp)
  90. BEGIN_SCOPE(Cn3D)
  91. // global strings for various directories - will include trailing path separator character
  92. static string
  93.     workingDir,     // current working directory
  94.     programDir,     // directory where Cn3D executable lives
  95.     dataDir,        // 'data' directory with external data files
  96.     prefsDir;       // application preferences directory
  97. const string& GetWorkingDir(void) { return workingDir; }
  98. const string& GetProgramDir(void) { return programDir; }
  99. const string& GetDataDir(void) { return dataDir; }
  100. const string& GetPrefsDir(void) { return prefsDir; }
  101. // top-level window (the main structure window)
  102. static wxFrame *topWindow = NULL;
  103. wxFrame * GlobalTopWindow(void) { return topWindow; }
  104. // Set the NCBI diagnostic streams to go to this method, which then pastes them
  105. // into a wxWindow. This log window can be closed anytime, but will be hidden,
  106. // not destroyed. More serious errors will bring up a dialog, so that the user
  107. // will get a chance to see the error before the program halts upon a fatal error.
  108. class MsgFrame;
  109. static MsgFrame *logFrame = NULL;
  110. static list < string > backLog;
  111. class MsgFrame : public wxFrame
  112. {
  113. public:
  114.     wxTextCtrl *logText;
  115.     int totalChars;
  116.     MsgFrame(const wxString& title,
  117.         const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize) :
  118.         wxFrame(GlobalTopWindow(), wxID_HIGHEST + 5, title, pos, size,
  119.             wxDEFAULT_FRAME_STYLE
  120. #if defined(__WXMSW__)
  121.                 | wxFRAME_TOOL_WINDOW | wxFRAME_NO_TASKBAR | wxFRAME_FLOAT_ON_PARENT
  122. #endif
  123.             )
  124.     {
  125.         totalChars = 0;
  126.         SetIcon(wxICON(cn3d));
  127.     }
  128.     ~MsgFrame(void) { logFrame = NULL; logText = NULL; }
  129. private:
  130.     // need to define a custom close window handler, so that window isn't actually destroyed,
  131.     // just hidden when user closes it with system close button
  132.     void OnCloseWindow(wxCloseEvent& event);
  133.     DECLARE_EVENT_TABLE()
  134. };
  135. BEGIN_EVENT_TABLE(MsgFrame, wxFrame)
  136.     EVT_CLOSE(MsgFrame::OnCloseWindow)
  137. END_EVENT_TABLE()
  138. void MsgFrame::OnCloseWindow(wxCloseEvent& event)
  139. {
  140.     if (event.CanVeto()) {
  141.         Show(false);
  142.         event.Veto();
  143.     } else {
  144.         Destroy();
  145.         logFrame = NULL;
  146.     }
  147. }
  148. static bool dialogSevereErrors = true;
  149. void SetDialogSevereErrors(bool status)
  150. {
  151.     dialogSevereErrors = status;
  152. }
  153. void DisplayDiagnostic(const SDiagMessage& diagMsg)
  154. {
  155.     string errMsg;
  156.     diagMsg.Write(errMsg);
  157.     // severe errors get a special error dialog
  158.     if (diagMsg.m_Severity >= eDiag_Error && diagMsg.m_Severity != eDiag_Trace && dialogSevereErrors) {
  159.         wxMessageDialog dlg(NULL, errMsg.c_str(), "Severe Error!", wxOK | wxCENTRE | wxICON_EXCLAMATION);
  160.         dlg.ShowModal();
  161.     }
  162.     // info messages and less severe errors get added to the log
  163.     else {
  164.         if (logFrame) {
  165.             // delete top of log if too big
  166.             if (logFrame->totalChars + errMsg.size() > 100000) {
  167.                 logFrame->logText->Clear();
  168.                 logFrame->totalChars = 0;
  169.             }
  170.             logFrame->logText->SetInsertionPoint(logFrame->logText->GetLastPosition());
  171.             *(logFrame->logText) << errMsg.c_str();
  172.             logFrame->totalChars += errMsg.size();
  173.         } else {
  174.             // if message window doesn't exist yet, store messages until later
  175.             backLog.push_back(errMsg.c_str());
  176.         }
  177.     }
  178. }
  179. void RaiseLogWindow(void)
  180. {
  181.     if (!logFrame) {
  182.         logFrame = new MsgFrame("Cn3D Message Log", wxPoint(500, 0), wxSize(500, 500));
  183. #ifdef __WXMAC__
  184.         // make empty menu for this window
  185.         wxMenuBar *menuBar = new wxMenuBar;
  186.         logFrame->SetMenuBar(menuBar);
  187. #endif
  188.         logFrame->SetSizeHints(150, 100);
  189.         logFrame->logText = new wxTextCtrl(logFrame, -1, "",
  190.             wxPoint(0,0), logFrame->GetClientSize(), wxTE_RICH | wxTE_MULTILINE | wxTE_READONLY | wxHSCROLL);
  191.         // display any messages received before window created
  192.         while (backLog.size() > 0) {
  193.             *(logFrame->logText) << backLog.front().c_str();
  194.             logFrame->totalChars += backLog.front().size();
  195.             backLog.erase(backLog.begin());
  196.         }
  197.     }
  198.     logFrame->logText->ShowPosition(logFrame->logText->GetLastPosition());
  199.     logFrame->Show(true);
  200. #if defined(__WXMSW__)
  201.     if (logFrame->IsIconized()) logFrame->Maximize(false);
  202. #endif
  203.     logFrame->Raise();
  204. }
  205. BEGIN_EVENT_TABLE(Cn3DApp, wxGLApp)
  206.     EVT_IDLE(Cn3DApp::OnIdle)
  207. END_EVENT_TABLE()
  208. Cn3DApp::Cn3DApp() : wxGLApp()
  209. {
  210.     // setup the diagnostic stream
  211.     SetDiagHandler(DisplayDiagnostic, NULL, NULL);
  212.     SetDiagPostLevel(eDiag_Info);   // report all messages
  213.     SetDiagTrace(eDT_Default);      // trace messages only when DIAG_TRACE env. var. is set
  214. #ifdef _DEBUG
  215.     SetDiagPostFlag(eDPF_File);
  216.     SetDiagPostFlag(eDPF_Line);
  217. #else
  218.     UnsetDiagTraceFlag(eDPF_File);
  219.     UnsetDiagTraceFlag(eDPF_Line);
  220. #endif
  221.     SetupCToolkitErrPost(); // reroute C-toolkit err messages to C++ err streams
  222.     // C++ object verification
  223.     CSerialObject::SetVerifyDataGlobal(eSerialVerifyData_Always);
  224.     CObjectIStream::SetVerifyDataGlobal(eSerialVerifyData_Always);
  225.     CObjectOStream::SetVerifyDataGlobal(eSerialVerifyData_Always);
  226.     if (!InitGLVisual(NULL))
  227.         FATALMSG("InitGLVisual failed");
  228. }
  229. void Cn3DApp::InitRegistry(void)
  230. {
  231.     // first set up defaults, then override any/all with stuff from registry file
  232.     // default log window startup
  233.     RegistrySetBoolean(REG_CONFIG_SECTION, REG_SHOW_LOG_ON_START, false);
  234.     RegistrySetString(REG_CONFIG_SECTION, REG_FAVORITES_NAME, NO_FAVORITES_FILE);
  235.     // default animation controls
  236.     RegistrySetInteger(REG_ANIMATION_SECTION, REG_SPIN_DELAY, 50);
  237.     RegistrySetDouble(REG_ANIMATION_SECTION, REG_SPIN_INCREMENT, 2.0),
  238.     RegistrySetInteger(REG_ANIMATION_SECTION, REG_FRAME_DELAY, 500);
  239.     // default quality settings
  240.     RegistrySetInteger(REG_QUALITY_SECTION, REG_QUALITY_ATOM_SLICES, 10);
  241.     RegistrySetInteger(REG_QUALITY_SECTION, REG_QUALITY_ATOM_STACKS, 8);
  242.     RegistrySetInteger(REG_QUALITY_SECTION, REG_QUALITY_BOND_SIDES, 6);
  243.     RegistrySetInteger(REG_QUALITY_SECTION, REG_QUALITY_WORM_SIDES, 6);
  244.     RegistrySetInteger(REG_QUALITY_SECTION, REG_QUALITY_WORM_SEGMENTS, 6);
  245.     RegistrySetInteger(REG_QUALITY_SECTION, REG_QUALITY_HELIX_SIDES, 12);
  246.     RegistrySetBoolean(REG_QUALITY_SECTION, REG_HIGHLIGHTS_ON, true);
  247.     RegistrySetString(REG_QUALITY_SECTION, REG_PROJECTION_TYPE, "Perspective");
  248.     // default font for OpenGL (structure window)
  249.     wxFont *font = wxFont::New(
  250. #if defined(__WXMSW__)
  251.         12,
  252. #elif defined(__WXGTK__)
  253.         14,
  254. #elif defined(__WXMAC__)
  255.         14,
  256. #endif
  257.         wxSWISS, wxNORMAL, wxBOLD, false);
  258.     if (font && font->Ok())
  259.         RegistrySetString(REG_OPENGL_FONT_SECTION, REG_FONT_NATIVE_FONT_INFO,
  260. font->GetNativeFontInfoDesc().c_str());
  261.     else
  262.         ERRORMSG("Can't create default structure window font");
  263.     if (font) delete font;
  264.     // default font for sequence viewers
  265.     font = wxFont::New(
  266. #if defined(__WXMSW__)
  267.         10,
  268. #elif defined(__WXGTK__)
  269.         14,
  270. #elif defined(__WXMAC__)
  271.         12,
  272. #endif
  273.         wxROMAN, wxNORMAL, wxNORMAL, false);
  274.     if (font && font->Ok())
  275.         RegistrySetString(REG_SEQUENCE_FONT_SECTION, REG_FONT_NATIVE_FONT_INFO,
  276. font->GetNativeFontInfoDesc().c_str());
  277.     else
  278.         ERRORMSG("Can't create default sequence window font");
  279.     if (font) delete font;
  280.     // default cache settings
  281.     RegistrySetBoolean(REG_CACHE_SECTION, REG_CACHE_ENABLED, true);
  282.     if (GetPrefsDir().size() > 0)
  283.         RegistrySetString(REG_CACHE_SECTION, REG_CACHE_FOLDER, GetPrefsDir() + "cache");
  284.     else
  285.         RegistrySetString(REG_CACHE_SECTION, REG_CACHE_FOLDER, GetProgramDir() + "cache");
  286.     RegistrySetInteger(REG_CACHE_SECTION, REG_CACHE_MAX_SIZE, 25);
  287.     // default advanced options
  288.     RegistrySetBoolean(REG_ADVANCED_SECTION, REG_CDD_ANNOT_READONLY, true);
  289. #ifdef __WXGTK__
  290.     RegistrySetString(REG_ADVANCED_SECTION, REG_BROWSER_LAUNCH,
  291.         // for launching netscape in a separate window
  292.         "( netscape -noraise -remote 'openURL(<URL>,new-window)' || netscape '<URL>' ) >/dev/null 2>&1 &"
  293.         // for launching netscape in an existing window
  294. //        "( netscape -raise -remote 'openURL(<URL>)' || netscape '<URL>' ) >/dev/null 2>&1 &"
  295.     );
  296. #endif
  297.     RegistrySetInteger(REG_ADVANCED_SECTION, REG_MAX_N_STRUCTS, 10);
  298.     RegistrySetInteger(REG_ADVANCED_SECTION, REG_FOOTPRINT_RES, 15);
  299.     // default stereo options
  300.     RegistrySetDouble(REG_ADVANCED_SECTION, REG_STEREO_SEPARATION, 5.0);
  301.     RegistrySetBoolean(REG_ADVANCED_SECTION, REG_PROXIMAL_STEREO, true);
  302.     // load program registry - overriding defaults if present
  303.     LoadRegistry();
  304. }
  305. static CNcbi_mime_asn1 * CreateMimeFromBiostruc(const wxString& filename, EModel_type model)
  306. {
  307.     // read Biostruc
  308.     CRef < CBiostruc > biostruc(new CBiostruc());
  309.     string err;
  310.     SetDiagPostLevel(eDiag_Fatal); // ignore all but Fatal errors while reading data
  311.     bool okay = (ReadASNFromFile(filename.c_str(), biostruc.GetPointer(), true, &err) ||
  312.                  ReadASNFromFile(filename.c_str(), biostruc.GetPointer(), false, &err));
  313.     SetDiagPostLevel(eDiag_Info);
  314.     if (!okay) {
  315.         ERRORMSG("This file is not a valid Biostruc");
  316.         return NULL;
  317.     }
  318.     // remove all but desired model coordinates
  319.     CRef < CBiostruc_model > desiredModel;
  320.     CBiostruc::TModel::const_iterator m, me = biostruc->GetModel().end();
  321.     for (m=biostruc->GetModel().begin(); m!=me; ++m) {
  322.         if ((*m)->GetType() == model) {
  323.             desiredModel = *m;
  324.             break;
  325.         }
  326.     }
  327.     if (desiredModel.Empty()) {
  328.         ERRORMSG("Ack! There's no appropriate model in this Biostruc");
  329.         return NULL;
  330.     }
  331.     biostruc->ResetModel();
  332.     biostruc->SetModel().push_back(desiredModel);
  333.     // package Biostruc inside a mime object
  334.     CRef < CNcbi_mime_asn1 > mime(new CNcbi_mime_asn1());
  335.     CRef < CBiostruc_seq > strucseq(new CBiostruc_seq());
  336.     mime->SetStrucseq(*strucseq);
  337.     strucseq->SetStructure(*biostruc);
  338.     // get list of gi's to import
  339.     vector < int > gis;
  340.     CBiostruc_graph::TMolecule_graphs::const_iterator g,
  341.         ge = biostruc->GetChemical_graph().GetMolecule_graphs().end();
  342.     for (g=biostruc->GetChemical_graph().GetMolecule_graphs().begin(); g!=ge; ++g) {
  343.         if ((*g)->IsSetSeq_id() && (*g)->GetSeq_id().IsGi())
  344.             gis.push_back((*g)->GetSeq_id().GetGi());
  345.     }
  346.     if (gis.size() == 0) {
  347.         ERRORMSG("Can't find any sequence gi identifiers in this Biostruc");
  348.         return NULL;
  349.     }
  350.     // fetch sequences and store in mime
  351.     CRef < CSeq_entry > seqs(new CSeq_entry());
  352.     strucseq->SetSequences().push_back(seqs);
  353.     CRef < CBioseq_set > seqset(new CBioseq_set());
  354.     seqs->SetSet(*seqset);
  355.     for (int i=0; i<gis.size(); ++i) {
  356.         wxString id;
  357.         id.Printf("%i", gis[i]);
  358.         CRef < CBioseq > bioseq = FetchSequenceViaHTTP(id.c_str());
  359.         if (bioseq.NotEmpty()) {
  360.             CRef < CSeq_entry > seqentry(new CSeq_entry());
  361.             seqentry->SetSeq(*bioseq);
  362.             seqset->SetSeq_set().push_back(seqentry);
  363.         } else {
  364.             ERRORMSG("Failed to retrieve all Bioseqs");
  365.             return NULL;
  366.         }
  367.     }
  368.     return mime.Release();
  369. }
  370. bool Cn3DApp::OnInit(void)
  371. {
  372.     INFOMSG("Welcome to Cn3D " << CN3D_VERSION_STRING << "!");
  373.     INFOMSG("built " << __DATE__ << " with wxWidgets " << wxVERSION_NUM_DOT_STRING);
  374.     // set up command line parser
  375.     static const wxCmdLineEntryDesc cmdLineDesc[] = {
  376.         { wxCMD_LINE_SWITCH, "h", "help", "show this help message",
  377.             wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
  378.         { wxCMD_LINE_SWITCH, "r", "readonly", "message file is read-only",
  379.             wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL },
  380.         { wxCMD_LINE_SWITCH, "i", "imports", "show imports window on startup",
  381.             wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL },
  382.         { wxCMD_LINE_SWITCH, "n", "noalign", "do not show alignment window on startup",
  383.             wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL },
  384.         { wxCMD_LINE_SWITCH, "f", "force", "force saves to same file",
  385.             wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL },
  386.         { wxCMD_LINE_OPTION, "m", "message", "message file",
  387.             wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_NEEDS_SEPARATOR },
  388.         { wxCMD_LINE_OPTION, "a", "targetapp", "messaging target application name",
  389.             wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_NEEDS_SEPARATOR },
  390.         { wxCMD_LINE_OPTION, "o", "model", "model choice: alpha, single, or PDB",
  391.             wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_NEEDS_SEPARATOR },
  392.         { wxCMD_LINE_OPTION, "d", "id", "MMDB/PDB ID to load via network",
  393.             wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_NEEDS_SEPARATOR },
  394.         { wxCMD_LINE_PARAM, NULL, NULL, "input file",
  395.             wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL},
  396.         { wxCMD_LINE_NONE }
  397.     };
  398.     commandLine.SetSwitchChars("-");
  399.     commandLine.SetDesc(cmdLineDesc);
  400.     commandLine.SetCmdLine(argc, argv);
  401.     switch (commandLine.Parse()) {
  402.         case 0: TRACEMSG("command line parsed successfully"); break;
  403.         default: return false;  // exit upon either help or syntax error
  404.     }
  405.     // help system loads from zip file
  406.     wxFileSystem::AddHandler(new wxZipFSHandler);
  407.     // set up working directories
  408.     workingDir = wxGetCwd().c_str();
  409. #ifdef __WXGTK__
  410.     if (getenv("CN3D_HOME") != NULL)
  411.         programDir = getenv("CN3D_HOME");
  412.     else
  413. #endif
  414.     if (wxIsAbsolutePath(argv[0]))
  415.         programDir = wxPathOnly(argv[0]).c_str();
  416.     else if (wxPathOnly(argv[0]) == "")
  417.         programDir = workingDir;
  418.     else
  419.         programDir = workingDir + wxFILE_SEP_PATH + wxPathOnly(argv[0]).c_str();
  420.     workingDir = workingDir + wxFILE_SEP_PATH;
  421.     programDir = programDir + wxFILE_SEP_PATH;
  422.     // find or create preferences folder
  423.     wxString localDir;
  424.     wxSplitPath((wxFileConfig::GetLocalFileName("unused")).c_str(), &localDir, NULL, NULL);
  425.     wxString prefsDirLocal = localDir + wxFILE_SEP_PATH + "Cn3D_User";
  426.     wxString prefsDirProg = wxString(programDir.c_str()) + wxFILE_SEP_PATH + "Cn3D_User";
  427.     if (wxDirExists(prefsDirLocal))
  428.         prefsDir = prefsDirLocal.c_str();
  429.     else if (wxDirExists(prefsDirProg))
  430.         prefsDir = prefsDirProg.c_str();
  431.     else {
  432.         // try to create the folder
  433.         if (wxMkdir(prefsDirLocal) && wxDirExists(prefsDirLocal))
  434.             prefsDir = prefsDirLocal.c_str();
  435.         else if (wxMkdir(prefsDirProg) && wxDirExists(prefsDirProg))
  436.             prefsDir = prefsDirProg.c_str();
  437.     }
  438.     if (prefsDir.size() == 0)
  439.         WARNINGMSG("Can't create Cn3D_User folder at either:"
  440.             << "n    " << prefsDirLocal
  441.             << "nor  " << prefsDirProg);
  442.     else
  443.         prefsDir += wxFILE_SEP_PATH;
  444.     // set data dir, and register the path in C toolkit registry (mainly for BLAST code)
  445. #ifdef __WXMAC__
  446.     dataDir = programDir + "../Resources/data/";
  447. #else
  448.     dataDir = programDir + "data" + wxFILE_SEP_PATH;
  449. #endif
  450.     Nlm_TransientSetAppParam("ncbi", "ncbi", "data", dataDir.c_str());
  451.     INFOMSG("working dir: " << workingDir.c_str());
  452.     INFOMSG("program dir: " << programDir.c_str());
  453.     INFOMSG("data dir: " << dataDir.c_str());
  454.     INFOMSG("prefs dir: " << prefsDir.c_str());
  455.     // read dictionary
  456.     wxString dictFile = wxString(dataDir.c_str()) + "bstdt.val";
  457.     LoadStandardDictionary(dictFile.c_str());
  458.     // set up registry and favorite styles (must be done before structure window creation)
  459.     InitRegistry();
  460.     // create the main frame window - must be first window created by the app
  461.     structureWindow = new StructureWindow(
  462.         wxString("Cn3D ") + CN3D_VERSION_STRING, wxPoint(0,0), wxSize(500,500));
  463.     SetTopWindow(structureWindow);
  464.     SetExitOnFrameDelete(true); // exit app when structure window is closed
  465.     topWindow = structureWindow;
  466.     // show log if set to do so
  467.     bool showLog = false;
  468.     RegistryGetBoolean(REG_CONFIG_SECTION, REG_SHOW_LOG_ON_START, &showLog);
  469.     if (showLog) RaiseLogWindow();
  470.     // get model type from -o
  471.     EModel_type model = eModel_type_other;
  472.     wxString modelStr;
  473.     if (commandLine.Found("o", &modelStr)) {
  474.         if (modelStr == "alpha")
  475.             model = eModel_type_ncbi_backbone;
  476.         else if (modelStr == "single")
  477.             model = eModel_type_ncbi_all_atom;
  478.         else if (modelStr == "PDB")
  479.             model = eModel_type_pdb_model;
  480.         else
  481.             ERRORMSG("Model type (-o) must be one of alpha|single|PDB");
  482.     }
  483.     // load file given on command line
  484.     if (commandLine.GetParamCount() == 1) {
  485.         wxString filename = commandLine.GetParam(0).c_str();
  486.         INFOMSG("command line file: " << filename.c_str());
  487.         // if -o is present, assume param is a Biostruc file
  488.         if (model != eModel_type_other) {   // -o present
  489.             CNcbi_mime_asn1 *mime = CreateMimeFromBiostruc(filename, model);
  490.             if (mime)
  491.                 structureWindow->LoadData(NULL, commandLine.Found("f"), mime);
  492.         } else {
  493.             structureWindow->LoadData(filename.c_str(), commandLine.Found("f"));
  494.         }
  495.     }
  496.     // if no file passed but there is -o, see if there's a -d parameter (MMDB/PDB ID to fetch)
  497.     else if (model != eModel_type_other) {  // -o present
  498.         wxString id;
  499.         if (commandLine.Found("d", &id)) {
  500.             CNcbi_mime_asn1 *mime = LoadStructureViaCache(id.c_str(), model);
  501.             if (mime)
  502.                 structureWindow->LoadData(NULL, commandLine.Found("f"), mime);
  503.         } else {
  504.             ERRORMSG("-o requires either -d or Biostruc file name");
  505.         }
  506.     }
  507.     // if no structure loaded, show the logo
  508.     if (!structureWindow->glCanvas->structureSet) {
  509.         structureWindow->glCanvas->renderer->AttachStructureSet(NULL);
  510.         structureWindow->glCanvas->Refresh(false);
  511.     }
  512.     // set up messaging file communication
  513.     wxString messageFilename;
  514.     if (commandLine.Found("m", &messageFilename)) {
  515.         wxString messageApp;
  516.         if (!commandLine.Found("a", &messageApp))
  517.             messageApp = "Listener";
  518.         structureWindow->SetupFileMessenger(
  519.             messageFilename.c_str(), messageApp.c_str(), commandLine.Found("r"));
  520.     }
  521.     // optionally show alignment window
  522.     if (!commandLine.Found("n") && structureWindow->glCanvas->structureSet)
  523.         structureWindow->glCanvas->structureSet->alignmentManager->ShowSequenceViewer();
  524.     // optionally open imports window, but only if any imports present
  525.     if (commandLine.Found("i") && structureWindow->glCanvas->structureSet &&
  526.             structureWindow->glCanvas->structureSet->alignmentManager->NUpdates() > 0)
  527.         structureWindow->glCanvas->structureSet->alignmentManager->ShowUpdateWindow();
  528.     // give structure window initial focus
  529.     structureWindow->Raise();
  530.     structureWindow->SetFocus();
  531.     return true;
  532. }
  533. int Cn3DApp::OnExit(void)
  534. {
  535.     SetDiagHandler(NULL, NULL, NULL);
  536.     SetDiagStream(&cout);
  537.     // save registry
  538.     SaveRegistry();
  539.     // remove dictionary
  540.     DeleteStandardDictionary();
  541.     // destroy log
  542.     if (logFrame) logFrame->Destroy();
  543.     return 0;
  544. }
  545. void Cn3DApp::OnIdle(wxIdleEvent& event)
  546. {
  547.     // process pending redraws
  548.     GlobalMessenger()->ProcessRedraws();
  549.     // call base class OnIdle to continue processing any other system idle-time stuff
  550.     wxApp::OnIdle(event);
  551. }
  552. #ifdef __WXMAC__
  553. // special handler for open file apple event
  554. void Cn3DApp::MacOpenFile(const wxString& filename)
  555. {
  556.     if (filename.size() > 0) {
  557.         INFOMSG("apple open event file: " << filename);
  558.         structureWindow->LoadData(filename, false);
  559.     }
  560. }
  561. #endif
  562. END_SCOPE(Cn3D)
  563. /*
  564. * ---------------------------------------------------------------------------
  565. * $Log: cn3d_app.cpp,v $
  566. * Revision 1000.3  2004/06/01 18:28:05  gouriano
  567. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.21
  568. *
  569. * Revision 1.21  2004/05/22 15:33:41  thiessen
  570. * fix scrolling bug in log frame
  571. *
  572. * Revision 1.20  2004/05/21 21:41:39  gorelenk
  573. * Added PCH ncbi_pch.hpp
  574. *
  575. * Revision 1.19  2004/04/19 19:36:07  thiessen
  576. * fix frame switch bug when no structures present
  577. *
  578. * Revision 1.18  2004/03/15 18:19:23  thiessen
  579. * prefer prefix vs. postfix ++/-- operators
  580. *
  581. * Revision 1.17  2004/03/10 23:15:51  thiessen
  582. * add ability to turn off/on error dialogs; group block aligner errors in message log
  583. *
  584. * Revision 1.16  2004/02/19 17:04:47  thiessen
  585. * remove cn3d/ from include paths; add pragma to disable annoying msvc warning
  586. *
  587. * Revision 1.15  2004/01/28 19:27:54  thiessen
  588. * add input asn stream verification
  589. *
  590. * Revision 1.14  2004/01/17 02:11:27  thiessen
  591. * mac fix
  592. *
  593. * Revision 1.13  2004/01/17 01:47:26  thiessen
  594. * add network load
  595. *
  596. * Revision 1.12  2004/01/17 00:17:28  thiessen
  597. * add Biostruc and network structure load
  598. *
  599. * Revision 1.11  2004/01/08 15:31:02  thiessen
  600. * remove hard-coded CDTree references in messaging; add Cn3DTerminated message upon exit
  601. *
  602. * Revision 1.10  2003/12/03 15:46:36  thiessen
  603. * adjust so spin increment is accurate
  604. *
  605. * Revision 1.9  2003/12/03 15:07:09  thiessen
  606. * add more sophisticated animation controls
  607. *
  608. * Revision 1.8  2003/11/15 16:08:35  thiessen
  609. * add stereo
  610. *
  611. * Revision 1.7  2003/10/13 14:16:31  thiessen
  612. * add -n option to not show alignment window
  613. *
  614. * Revision 1.6  2003/10/13 13:23:31  thiessen
  615. * add -i option to show import window
  616. *
  617. * Revision 1.5  2003/07/17 18:47:01  thiessen
  618. * add -f option to force save to same file
  619. *
  620. * Revision 1.4  2003/06/21 20:54:03  thiessen
  621. * explicitly show bottom of log when new text appended
  622. *
  623. * Revision 1.3  2003/05/29 14:34:19  thiessen
  624. * force serial object verification
  625. *
  626. * Revision 1.2  2003/03/13 16:57:14  thiessen
  627. * fix favorites load/save problem
  628. *
  629. * Revision 1.1  2003/03/13 14:26:18  thiessen
  630. * add file_messaging module; split cn3d_main_wxwin into cn3d_app, cn3d_glcanvas, structure_window, cn3d_tools
  631. *
  632. */