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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: messenger.cpp,v $
  4.  * PRODUCTION Revision 1000.3  2004/06/01 18:28:39  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.42
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: messenger.cpp,v 1000.3 2004/06/01 18:28:39 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. *      Classes to handle messaging and communication between sequence
  38. *      and structure windows
  39. *
  40. * ===========================================================================
  41. */
  42. #ifdef _MSC_VER
  43. #pragma warning(disable:4018)   // disable signed/unsigned mismatch warning in MSVC
  44. #endif
  45. #include <ncbi_pch.hpp>
  46. #include <corelib/ncbistd.hpp>
  47. #include <memory>
  48. #include <objects/mmdb1/Biostruc_id.hpp>
  49. #include <objects/mmdb1/Mmdb_id.hpp>
  50. #include <objects/mmdb3/Biostruc_feature_set.hpp>
  51. #include <objects/mmdb3/Biostruc_feature_set_id.hpp>
  52. #include <objects/mmdb3/Biostruc_feature.hpp>
  53. #include <objects/mmdb3/Chem_graph_pntrs.hpp>
  54. #include <objects/mmdb3/Residue_pntrs.hpp>
  55. #include <objects/mmdb3/Residue_interval_pntr.hpp>
  56. #include <objects/mmdb1/Molecule_id.hpp>
  57. #include <objects/mmdb1/Residue_id.hpp>
  58. #include "messenger.hpp"
  59. #include "structure_window.hpp"
  60. #include "cn3d_glcanvas.hpp"
  61. #include "sequence_viewer.hpp"
  62. #include "opengl_renderer.hpp"
  63. #include "structure_set.hpp"
  64. #include "chemical_graph.hpp"
  65. #include "sequence_set.hpp"
  66. #include "molecule_identifier.hpp"
  67. #include "cn3d_tools.hpp"
  68. USING_NCBI_SCOPE;
  69. USING_SCOPE(objects);
  70. BEGIN_SCOPE(Cn3D)
  71. // the global Messenger object
  72. static Messenger messenger;
  73. Messenger * GlobalMessenger(void)
  74. {
  75.     return &messenger;
  76. }
  77. void Messenger::PostRedrawAllStructures(void)
  78. {
  79.     redrawAllStructures = true;
  80.     redrawMolecules.clear();
  81. }
  82. void Messenger::PostRedrawMolecule(const Molecule *molecule)
  83. {
  84.     if (!redrawAllStructures) redrawMolecules[molecule] = true;
  85. }
  86. void Messenger::PostRedrawAllSequenceViewers(void)
  87. {
  88.     redrawAllSequenceViewers = true;
  89.     redrawSequenceViewers.clear();
  90. }
  91. void Messenger::PostRedrawSequenceViewer(ViewerBase *viewer)
  92. {
  93.     if (!redrawAllSequenceViewers) redrawSequenceViewers[viewer] = true;
  94. }
  95. void Messenger::UnPostRedrawAllSequenceViewers(void)
  96. {
  97.     redrawAllSequenceViewers = false;
  98.     redrawSequenceViewers.clear();
  99. }
  100. void Messenger::UnPostRedrawSequenceViewer(ViewerBase *viewer)
  101. {
  102.     if (redrawAllSequenceViewers) {
  103.         SequenceViewerList::const_iterator q, qe = sequenceViewers.end();
  104.         for (q=sequenceViewers.begin(); q!=qe; ++q) redrawSequenceViewers[*q] = true;
  105.         redrawAllSequenceViewers = false;
  106.     }
  107.     RedrawSequenceViewerList::iterator f = redrawSequenceViewers.find(viewer);
  108.     if (f != redrawSequenceViewers.end()) redrawSequenceViewers.erase(f);
  109. }
  110. void Messenger::UnPostStructureRedraws(void)
  111. {
  112.     redrawAllStructures = false;
  113.     redrawMolecules.clear();
  114. }
  115. void Messenger::ProcessRedraws(void)
  116. {
  117.     if (redrawAllSequenceViewers) {
  118.         SequenceViewerList::const_iterator q, qe = sequenceViewers.end();
  119.         for (q=sequenceViewers.begin(); q!=qe; ++q) (*q)->Refresh();
  120.         redrawAllSequenceViewers = false;
  121.     }
  122.     else if (redrawSequenceViewers.size() > 0) {
  123.         RedrawSequenceViewerList::const_iterator q, qe = redrawSequenceViewers.end();
  124.         for (q=redrawSequenceViewers.begin(); q!=qe; ++q) q->first->Refresh();
  125.         redrawSequenceViewers.clear();
  126.     }
  127.     if (redrawAllStructures) {
  128.         if (structureWindow) {
  129.             structureWindow->glCanvas->SetCurrent();
  130.             structureWindow->glCanvas->renderer->Construct();
  131.             structureWindow->glCanvas->renderer->NewView();
  132.             structureWindow->glCanvas->Refresh(false);
  133.         }
  134. redrawAllStructures = false;
  135.     }
  136.     else if (redrawMolecules.size() > 0) {
  137.         map < const StructureObject * , bool > hetsRedrawn;
  138.         RedrawMoleculeList::const_iterator m, me = redrawMolecules.end();
  139.         for (m=redrawMolecules.begin(); m!=me; ++m) {
  140.             const StructureObject *object;
  141.             if (!m->first->GetParentOfType(&object)) continue;
  142.             // hets/solvents are always redrawn with each molecule, so don't need to repeat
  143.             if ((m->first->IsSolvent() || m->first->IsHeterogen()) &&
  144.                 hetsRedrawn.find(object) != hetsRedrawn.end()) continue;
  145.             object->graph->RedrawMolecule(m->first->id);
  146.             hetsRedrawn[object] = true;
  147.         }
  148.         if (structureWindow) {
  149.             structureWindow->glCanvas->renderer->NewView();
  150.             structureWindow->glCanvas->Refresh(false);
  151.         }
  152.         redrawMolecules.clear();
  153.     }
  154. }
  155. void Messenger::RemoveStructureWindow(const StructureWindow *window)
  156. {
  157.     if (window != structureWindow)
  158.         ERRORMSG("Messenger::RemoveStructureWindow() - window mismatch");
  159.     structureWindow = NULL;
  160. }
  161. void Messenger::RemoveSequenceViewer(const ViewerBase *sequenceViewer)
  162. {
  163.     SequenceViewerList::iterator t, te = sequenceViewers.end();
  164.     for (t=sequenceViewers.begin(); t!=te; ++t) {
  165.         if (*t == sequenceViewer) sequenceViewers.erase(t);
  166.         break;
  167.     }
  168. }
  169. void Messenger::SequenceWindowsSave(bool prompt)
  170. {
  171.     SequenceViewerList::const_iterator q, qe = sequenceViewers.end();
  172.     for (q=sequenceViewers.begin(); q!=qe; ++q)
  173.         (*q)->SaveDialog(prompt);
  174. }
  175. void Messenger::NewSequenceViewerFont(void)
  176. {
  177.     SequenceViewerList::const_iterator q, qe = sequenceViewers.end();
  178.     for (q=sequenceViewers.begin(); q!=qe; ++q)
  179.         (*q)->NewFont();
  180. }
  181. ///// highlighting functions /////
  182. bool Messenger::IsHighlighted(const MoleculeIdentifier *identifier, int index) const
  183. {
  184.     if (highlightingSuspended) return false;
  185.     MoleculeHighlightMap::const_iterator h = highlights.find(identifier);
  186.     if (h == highlights.end()) return false;
  187.     if (index == -1) return true;   // special check for highlight anywhere
  188.     if (index < 0 || index >= h->second.size()) {
  189.         ERRORMSG("Messenger::IsHighlighted() - index out of range");
  190.         return false;
  191.     } else
  192.         return h->second[index];
  193. }
  194. bool Messenger::IsHighlighted(const Molecule *molecule, int residueID) const
  195. {
  196.     return IsHighlighted(molecule->identifier, residueID - 1);  // assume index = id - 1
  197. }
  198. bool Messenger::IsHighlighted(const Sequence *sequence, int seqIndex) const
  199. {
  200.     return IsHighlighted(sequence->identifier, seqIndex);
  201. }
  202. bool Messenger::IsHighlightedAnywhere(const MoleculeIdentifier *identifier) const
  203. {
  204.     return IsHighlighted(identifier, -1);
  205. }
  206. void Messenger::RedrawMoleculesWithIdentifier(const MoleculeIdentifier *identifier, const StructureSet *set)
  207. {
  208.     StructureSet::ObjectList::const_iterator o, oe = set->objects.end();
  209.     ChemicalGraph::MoleculeMap::const_iterator m, me;
  210.     for (o=set->objects.begin(); o!=oe; ++o) {
  211.         for (m=(*o)->graph->molecules.begin(), me=(*o)->graph->molecules.end(); m!=me; ++m) {
  212.             if (m->second->identifier == identifier)
  213.                 PostRedrawMolecule(m->second);
  214.         }
  215.     }
  216. }
  217. void Messenger::AddHighlights(const Sequence *sequence, int seqIndexFrom, int seqIndexTo)
  218. {
  219.     if (seqIndexFrom < 0 || seqIndexTo < 0 || seqIndexFrom > seqIndexTo ||
  220.         seqIndexFrom >= sequence->Length() ||
  221.         seqIndexTo >= sequence->Length()) {
  222.         ERRORMSG("Messenger::AddHighlights() - seqIndex out of range");
  223.         return;
  224.     }
  225.     MoleculeHighlightMap::iterator h = highlights.find(sequence->identifier);
  226.     if (h == highlights.end()) {
  227.         highlights[sequence->identifier].resize(sequence->Length(), false);
  228.         h = highlights.find(sequence->identifier);
  229.     }
  230.     for (int i=seqIndexFrom; i<=seqIndexTo; ++i) h->second[i] = true;
  231.     PostRedrawAllSequenceViewers();
  232.     RedrawMoleculesWithIdentifier(sequence->identifier, sequence->parentSet);
  233. }
  234. void Messenger::HighlightAndShowSequence(const Sequence *sequence)
  235. {
  236.     RemoveAllHighlights(true);
  237.     AddHighlights(sequence, 0, sequence->Length() - 1);
  238.     SequenceViewerList::const_iterator q, qe = sequenceViewers.end();
  239.     for (q=sequenceViewers.begin(); q!=qe; ++q)
  240.         (*q)->MakeSequenceVisible(sequence->identifier);
  241. }
  242. void Messenger::RemoveHighlights(const Sequence *sequence, int seqIndexFrom, int seqIndexTo)
  243. {
  244.     if (seqIndexFrom < 0 || seqIndexTo < 0 || seqIndexFrom > seqIndexTo ||
  245.         seqIndexFrom >= sequence->Length() ||
  246.         seqIndexTo >= sequence->Length()) {
  247.         ERRORMSG("Messenger::RemoveHighlights() - seqIndex out of range");
  248.         return;
  249.     }
  250.     MoleculeHighlightMap::iterator h = highlights.find(sequence->identifier);
  251.     if (h != highlights.end()) {
  252.         int i;
  253.         for (i=seqIndexFrom; i<=seqIndexTo; ++i) h->second[i] = false;
  254.         // remove sequence from store if no highlights left
  255.         for (i=0; i<sequence->Length(); ++i)
  256.             if (h->second[i] == true) break;
  257.         if (i == sequence->Length())
  258.             highlights.erase(h);
  259.         PostRedrawAllSequenceViewers();
  260.         RedrawMoleculesWithIdentifier(sequence->identifier, sequence->parentSet);
  261.     }
  262. }
  263. void Messenger::ToggleHighlights(const MoleculeIdentifier *identifier, int indexFrom, int indexTo,
  264.     const StructureSet *set)
  265. {
  266.     if (indexFrom < 0 || indexTo < 0 || indexFrom > indexTo ||
  267.         indexFrom >= identifier->nResidues || indexTo >= identifier->nResidues) {
  268.         ERRORMSG("Messenger::ToggleHighlights() - index out of range");
  269.         return;
  270.     }
  271.     MoleculeHighlightMap::iterator h = highlights.find(identifier);
  272.     if (h == highlights.end()) {
  273.         highlights[identifier].resize(identifier->nResidues, false);
  274.         h = highlights.find(identifier);
  275.     }
  276.     int i;
  277.     for (i=indexFrom; i<=indexTo; ++i) h->second[i] = !h->second[i];
  278.     // remove sequence from store if no highlights left
  279.     for (i=0; i<h->second.size(); ++i)
  280.         if (h->second[i] == true) break;
  281.     if (i == h->second.size())
  282.         highlights.erase(h);
  283.     PostRedrawAllSequenceViewers();
  284.     RedrawMoleculesWithIdentifier(identifier, set);
  285. }
  286. void Messenger::ToggleHighlights(const Sequence *sequence, int seqIndexFrom, int seqIndexTo)
  287. {
  288.     ToggleHighlights(sequence->identifier, seqIndexFrom, seqIndexTo, sequence->parentSet);
  289. }
  290. void Messenger::ToggleHighlight(const Molecule *molecule, int residueID, bool scrollViewersTo)
  291. {
  292.     // assume index = id - 1
  293.     ToggleHighlights(molecule->identifier, residueID - 1, residueID - 1, molecule->parentSet);
  294.     if (scrollViewersTo) {
  295.         // make selected residue visible in sequence viewers if residue is in displayed sequence
  296.         SequenceViewerList::iterator t, te = sequenceViewers.end();
  297.         for (t=sequenceViewers.begin(); t!=te; ++t)
  298.             (*t)->MakeResidueVisible(molecule, residueID - 1);
  299.     }
  300. }
  301. bool Messenger::RemoveAllHighlights(bool postRedraws)
  302. {
  303.     bool anyRemoved = highlights.size() > 0;
  304.     if (postRedraws) {
  305.         if (anyRemoved) PostRedrawAllSequenceViewers();
  306.         if (structureWindow) {
  307.             MoleculeHighlightMap::const_iterator h, he = highlights.end();
  308.             for (h=highlights.begin(); h!=he; ++h)
  309.                 RedrawMoleculesWithIdentifier(h->first, structureWindow->glCanvas->structureSet);
  310.         }
  311.     }
  312.     highlights.clear();
  313.     return anyRemoved;
  314. }
  315. void Messenger::SetHighlights(const MoleculeHighlightMap& newHighlights)
  316. {
  317.     RemoveAllHighlights(true);
  318.     highlights = newHighlights;
  319.     PostRedrawAllSequenceViewers();
  320.     if (structureWindow) {
  321.         MoleculeHighlightMap::const_iterator h, he = highlights.end();
  322.         for (h=highlights.begin(); h!=he; ++h)
  323.             RedrawMoleculesWithIdentifier(h->first, structureWindow->glCanvas->structureSet);
  324.     }
  325. }
  326. void Messenger::SuspendHighlighting(bool suspend)
  327. {
  328.     if (highlightingSuspended != suspend) {
  329.         highlightingSuspended = suspend;
  330.         if (IsAnythingHighlighted()) {
  331.             PostRedrawAllStructures();
  332.             PostRedrawAllSequenceViewers();
  333.         }
  334.     }
  335. }
  336. bool Messenger::GetHighlightedResiduesWithStructure(MoleculeHighlightMap *residues) const
  337. {
  338.     residues->clear();
  339.     if (!IsAnythingHighlighted()) return false;
  340.     MoleculeHighlightMap::const_iterator h, he = highlights.end();
  341.     for (h=highlights.begin(); h!=he; ++h) {
  342.         if (h->first->HasStructure())
  343.             (*residues)[h->first] = h->second;
  344.     }
  345.     return (residues->size() > 0);
  346. }
  347. CBiostruc_annot_set * Messenger::CreateBiostrucAnnotSetForHighlightsOnSingleObject(void) const
  348. {
  349.     if (!IsAnythingHighlighted()) {
  350.         ERRORMSG("Nothing highlighted");
  351.         return NULL;
  352.     }
  353.     // check to see that all highlights are on a single structure object
  354.     int mmdbID;
  355.     MoleculeHighlightMap::const_iterator h, he = highlights.end();
  356.     for (h=highlights.begin(); h!=he; ++h) {
  357.         if (h == highlights.begin()) mmdbID = h->first->mmdbID;
  358.         if (h->first->mmdbID == MoleculeIdentifier::VALUE_NOT_SET || h->first->mmdbID != mmdbID) {
  359.             ERRORMSG("All highlights must be on a single PDB structure");
  360.             return NULL;
  361.         }
  362.         if (h->first->moleculeID == MoleculeIdentifier::VALUE_NOT_SET) {
  363.             ERRORMSG("internal error - MoleculeIdentifier has no moleculeID");
  364.             return NULL;
  365.         }
  366.     }
  367.     // create the Biostruc-annot-set
  368.     CRef < CBiostruc_annot_set > bas(new CBiostruc_annot_set());
  369.     // set id
  370.     CRef < CBiostruc_id > bid(new CBiostruc_id());
  371.     bas->SetId().push_back(bid);
  372.     bid->SetMmdb_id().Set(mmdbID);
  373.     // create feature set and feature
  374.     CRef < CBiostruc_feature_set > bfs(new CBiostruc_feature_set());
  375.     bas->SetFeatures().push_back(bfs);
  376.     bfs->SetId().Set(1);
  377.     CRef < CBiostruc_feature > bf(new CBiostruc_feature());
  378.     bfs->SetFeatures().push_back(bf);
  379.     // create Chem-graph-pntrs with residues
  380.     CChem_graph_pntrs *cgp = new CChem_graph_pntrs();
  381.     bf->SetLocation().SetSubgraph(*cgp);
  382.     CResidue_pntrs *rp = new CResidue_pntrs();
  383.     cgp->SetResidues(*rp);
  384.     // add all residue intervals
  385.     for (h=highlights.begin(); h!=he; ++h) {
  386.         int first = 0, last = 0;
  387.         while (first < h->second.size()) {
  388.             // find first highlighted residue
  389.             while (first < h->second.size() && !h->second[first]) ++first;
  390.             if (first >= h->second.size()) break;
  391.             // find last in contiguous stretch of highlighted residues
  392.             last = first;
  393.             while (last + 1 < h->second.size() && h->second[last + 1]) ++last;
  394.             // add new interval to list
  395.             CRef < CResidue_interval_pntr > rip(new CResidue_interval_pntr());
  396.             rip->SetMolecule_id().Set(h->first->moleculeID);
  397.             rip->SetFrom().Set(first + 1);  // assume residueID == index + 1
  398.             rip->SetTo().Set(last + 1);
  399.             rp->SetInterval().push_back(rip);
  400.             first = last + 2;
  401.         }
  402.     }
  403.     return bas.Release();
  404. }
  405. bool Messenger::GetHighlightsForSelectionMessage(string *data) const
  406. {
  407.     data->erase();
  408.     if (!IsAnythingHighlighted()) return false;
  409.     CNcbiOstrstream oss;
  410.     MoleculeHighlightMap::const_iterator h, he = highlights.end();
  411.     for (h=highlights.begin(); h!=he; ++h) {
  412.         // add identifier
  413.         if (h->first->pdbID.size() > 0) {
  414.             oss << "pdb " << h->first->pdbID;
  415.             if (h->first->pdbChain != ' ')
  416.                 oss << '_' << (char) h->first->pdbChain;
  417.         } else if (h->first->gi != MoleculeIdentifier::VALUE_NOT_SET) {
  418.             oss << "gi " << h->first->gi;
  419.         } else if (h->first->accession.size() > 0) {
  420.             oss << "acc " << h->first->accession;
  421.         } else {
  422.             WARNINGMSG("Messenger::GetHighlightsForSelectionMessage() - unimplemented identifier type");
  423.             continue;
  424.         }
  425.         // add range(s)
  426.         int first = 0, last = 0;
  427.         while (first < h->second.size()) {
  428.             // find first highlighted residue
  429.             while (first < h->second.size() && !h->second[first]) ++first;
  430.             if (first >= h->second.size()) break;
  431.             // find last in contiguous stretch of highlighted residues
  432.             last = first;
  433.             while (last + 1 < h->second.size() && h->second[last + 1]) ++last;
  434.             // add new interval to list
  435.             oss << ' ' << first;
  436.             if (last > first)
  437.                 oss << '-' << last;
  438.             first = last + 2;
  439.         }
  440.         oss << 'n';
  441.     }
  442.     oss << '';
  443.     auto_ptr<char> d(oss.str());
  444.     *data = d.get();
  445.     return true;
  446. }
  447. void Messenger::SetAllWindowTitles(void) const
  448. {
  449.     SequenceViewerList::const_iterator q, qe = sequenceViewers.end();
  450.     for (q=sequenceViewers.begin(); q!=qe; ++q)
  451.         (*q)->SetWindowTitle();
  452.     if (structureWindow) structureWindow->SetWindowTitle();
  453. }
  454. bool Messenger::IsFileMessengerActive(void) const
  455. {
  456.     return (structureWindow && structureWindow->IsFileMessengerActive());
  457. }
  458. void Messenger::FileMessengerSend(const std::string& toApp,
  459.     const std::string& command, const std::string& data)
  460. {
  461.     if (structureWindow) structureWindow->SendCommand(toApp, command, data);
  462. }
  463. END_SCOPE(Cn3D)
  464. /*
  465. * ---------------------------------------------------------------------------
  466. * $Log: messenger.cpp,v $
  467. * Revision 1000.3  2004/06/01 18:28:39  gouriano
  468. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.42
  469. *
  470. * Revision 1.42  2004/05/21 21:41:39  gorelenk
  471. * Added PCH ncbi_pch.hpp
  472. *
  473. * Revision 1.41  2004/03/15 18:25:36  thiessen
  474. * prefer prefix vs. postfix ++/-- operators
  475. *
  476. * Revision 1.40  2004/02/19 17:04:56  thiessen
  477. * remove cn3d/ from include paths; add pragma to disable annoying msvc warning
  478. *
  479. * Revision 1.39  2004/01/08 15:31:02  thiessen
  480. * remove hard-coded CDTree references in messaging; add Cn3DTerminated message upon exit
  481. *
  482. * Revision 1.38  2003/11/15 16:08:36  thiessen
  483. * add stereo
  484. *
  485. * Revision 1.37  2003/07/10 18:47:29  thiessen
  486. * add CDTree->Select command
  487. *
  488. * Revision 1.36  2003/03/13 14:26:18  thiessen
  489. * add file_messaging module; split cn3d_main_wxwin into cn3d_app, cn3d_glcanvas, structure_window, cn3d_tools
  490. *
  491. * Revision 1.35  2003/02/03 19:20:04  thiessen
  492. * format changes: move CVS Log to bottom of file, remove std:: from .cpp files, and use new diagnostic macros
  493. *
  494. * Revision 1.34  2002/10/11 17:21:39  thiessen
  495. * initial Mac OSX build
  496. *
  497. * Revision 1.33  2002/10/07 13:29:31  thiessen
  498. * add double-click -> show row to taxonomy tree
  499. *
  500. * Revision 1.32  2002/09/09 13:38:23  thiessen
  501. * separate save and save-as
  502. *
  503. * Revision 1.31  2002/09/05 18:38:57  thiessen
  504. * add sort by highlights
  505. *
  506. * Revision 1.30  2002/08/15 22:13:14  thiessen
  507. * update for wx2.3.2+ only; add structure pick dialog; fix MultitextDialog bug
  508. *
  509. * Revision 1.29  2002/07/02 16:13:49  thiessen
  510. * allow for NULL structureWindow
  511. *
  512. * Revision 1.28  2002/06/05 14:28:39  thiessen
  513. * reorganize handling of window titles
  514. *
  515. * Revision 1.27  2002/03/04 15:52:13  thiessen
  516. * hide sequence windows instead of destroying ; add perspective/orthographic projection choice
  517. *
  518. * Revision 1.26  2002/02/05 18:53:24  thiessen
  519. * scroll to residue in sequence windows when selected in structure window
  520. *
  521. * Revision 1.25  2002/01/19 02:34:42  thiessen
  522. * fixes for changes in asn serialization API
  523. *
  524. * Revision 1.24  2001/12/12 14:04:13  thiessen
  525. * add missing object headers after object loader change
  526. *
  527. * Revision 1.23  2001/10/23 20:10:23  thiessen
  528. * fix scaling of fonts in high-res PNG output
  529. *
  530. * Revision 1.22  2001/10/01 16:04:24  thiessen
  531. * make CDD annotation window non-modal; add SetWindowTitle to viewers
  532. *
  533. * Revision 1.21  2001/08/27 00:06:23  thiessen
  534. * add structure evidence to CDD annotation
  535. *
  536. * Revision 1.20  2001/08/14 17:18:22  thiessen
  537. * add user font selection, store in registry
  538. *
  539. * Revision 1.19  2001/07/04 19:39:17  thiessen
  540. * finish user annotation system
  541. *
  542. * Revision 1.18  2001/06/29 18:13:57  thiessen
  543. * initial (incomplete) user annotation system
  544. *
  545. * Revision 1.17  2001/06/21 02:02:33  thiessen
  546. * major update to molecule identification and highlighting ; add toggle highlight (via alt)
  547. *
  548. * Revision 1.16  2001/05/11 02:10:42  thiessen
  549. * add better merge fail indicators; tweaks to windowing/taskbar
  550. *
  551. * Revision 1.15  2001/03/30 14:43:41  thiessen
  552. * show threader scores in status line; misc UI tweaks
  553. *
  554. * Revision 1.14  2001/03/22 00:33:17  thiessen
  555. * initial threading working (PSSM only); free color storage in undo stack
  556. *
  557. * Revision 1.13  2001/03/01 20:15:51  thiessen
  558. * major rearrangement of sequence viewer code into base and derived classes
  559. *
  560. * Revision 1.12  2001/02/22 00:30:06  thiessen
  561. * make directories global ; allow only one Sequence per StructureObject
  562. *
  563. * Revision 1.11  2000/12/15 15:51:47  thiessen
  564. * show/hide system installed
  565. *
  566. * Revision 1.10  2000/11/30 15:49:38  thiessen
  567. * add show/hide rows; unpack sec. struc. and domain features
  568. *
  569. * Revision 1.9  2000/11/02 16:56:02  thiessen
  570. * working editor undo; dynamic slave transforms
  571. *
  572. * Revision 1.8  2000/10/19 12:40:54  thiessen
  573. * avoid multiple sequence redraws with scroll set
  574. *
  575. * Revision 1.7  2000/10/12 02:14:56  thiessen
  576. * working block boundary editing
  577. *
  578. * Revision 1.6  2000/10/02 23:25:21  thiessen
  579. * working sequence identifier window in sequence viewer
  580. *
  581. * Revision 1.5  2000/09/15 19:24:22  thiessen
  582. * allow repeated structures w/o different local id
  583. *
  584. * Revision 1.4  2000/09/14 14:55:34  thiessen
  585. * add row reordering; misc fixes
  586. *
  587. * Revision 1.3  2000/09/11 22:57:32  thiessen
  588. * working highlighting
  589. *
  590. * Revision 1.2  2000/09/11 14:06:28  thiessen
  591. * working alignment coloring
  592. *
  593. * Revision 1.1  2000/09/11 01:46:14  thiessen
  594. * working messenger for sequence<->structure window communication
  595. *
  596. */