NCBI C++ ToolKit
command_processor.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: command_processor.cpp 87235 2019-08-09 15:27:34Z wangjiy $
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Authors: Paul Thiessen
27 *
28 * File Description:
29 * module to process external commands (e.g. from file messenger)
30 *
31 * Commands:
32 *
33 * Highlight:
34 * data is any number of the following, one per line separated by '\n':
35 * [identifier] \t [ranges]
36 * where [identifier] is an XML-format Seq-id
37 * where a tab character separates the identifier from the ranges
38 * where ranges is sequence of zero-numbered numerical positions or ranges,
39 * e.g. "1-100, 102, 105-192"
40 *
41 * LoadFile:
42 * data is the name of the file to load
43 *
44 * Exit:
45 * quit the program, same behaviour as hitting File:Exit or 'X' icon
46 *
47 * ===========================================================================
48 */
49 
50 #include <ncbi_pch.hpp>
51 #include <corelib/ncbistd.hpp>
52 
53 #include <list>
54 
56 
57 #include "command_processor.hpp"
58 #include "structure_window.hpp"
59 #include "cn3d_glcanvas.hpp"
60 #include "structure_set.hpp"
61 #include "cn3d_tools.hpp"
62 #include "messenger.hpp"
63 #include "sequence_set.hpp"
64 #include "molecule_identifier.hpp"
65 
66 #include <wx/tokenzr.h>
67 
70 
71 
72 BEGIN_SCOPE(Cn3D)
73 
74 // splits single string into multiple; assumes '\n'-terminated lines
75 static void SplitString(const string& inStr, list<string> *outList)
76 {
77  outList->clear();
78 
79  int firstPos = 0, size = 0;
80  for (unsigned int i=0; i<inStr.size(); ++i) {
81  if (inStr[i] == '\n') {
82  outList->resize(outList->size() + 1);
83  outList->back() = inStr.substr(firstPos, size);
84  firstPos = i + 1;
85  size = 0;
86 // TRACEMSG("outList: '" << outList->back() << "'");
87  } else if (i == inStr.size() - 1) {
88  ERRORMSG("SplitString() - input multi-line string doesn't end with \n!");
89  } else {
90  ++size;
91  }
92  }
93 }
94 
95 #define SPLIT_DATAIN_INTO_LINES \
96  list<string> lines; \
97  SplitString(dataIn, &lines); \
98  list<string>::const_iterator l, le = lines.end()
99 
101 {
102  TRACEMSG("processing " << command);
103  if (dataIn.size() > 0)
104  TRACEMSG("data:\n" << dataIn.substr(0, dataIn.size() - 1));
105  else
106  TRACEMSG("data: (none)");
107 
108  // process known commands
109  PROCESS_IF_COMMAND_IS(Highlight);
111  PROCESS_IF_COMMAND_IS(Exit);
112 
113  // will only get here if command isn't recognized
114  ADD_REPLY_ERROR("Unrecognized command");
115 }
116 
118 {
119  if (dataIn.size() == 0) {
120  ADD_REPLY_ERROR("no identifiers given");
121  return;
122  }
123 
124  // default response
126  dataOut->erase();
127 
129 
131  for (l=lines.begin(); l!=le; ++l) {
132 
133  vector < string > toks;
134  //NStr::Tokenize(*l, "\t", toks);
135  NStr::Split(*l, "\t", toks);
136  if (toks.size() != 2) {
137  ADD_REPLY_ERROR(string("invalid line, expected 'id' + tab + 'ranges': ") + *l);
138  continue;
139  }
140 
141  // sequence to highlight on
142  const Sequence *seq;
143 
144  // get identifier
145  list < CRef < CSeq_id > > idList;
146  idList.resize(1);
147  if (!IdentifierToSeqId(toks[0], idList.front())) {
148  ADD_REPLY_ERROR(string("unparseable id: ") + toks[0]);
149  continue;
150  }
151  seq = structureWindow->glCanvas->structureSet->sequenceSet->FindMatchingSequence(idList);
152  if (!seq) {
153  ADD_REPLY_ERROR(string("sequence not found: ") + toks[0]);
154  continue;
155  }
156 
157  // now parse ranges and highlight
158  wxStringTokenizer tkz(toks[1].c_str(), ", ", wxTOKEN_STRTOK);
159  while (tkz.HasMoreTokens()) {
160  wxString range = tkz.GetNextToken();
161  wxStringTokenizer rangeToks(range, "-", wxTOKEN_RET_EMPTY);
162  if (rangeToks.CountTokens() < 1 || rangeToks.CountTokens() > 2) {
163  ADD_REPLY_ERROR(string("bad range: ") + WX_TO_STD(range));
164  continue;
165  }
166  unsigned long from, to;
167  bool okay;
168  if (rangeToks.CountTokens() == 1) {
169  okay = rangeToks.GetNextToken().ToULong(&from);
170  to = from;
171  } else {
172  okay = (rangeToks.GetNextToken().ToULong(&from) && rangeToks.GetNextToken().ToULong(&to));
173  }
174  if (!okay || from >= seq->Length() || to >= seq->Length() || from > to) {
175  ADD_REPLY_ERROR(string("bad range value(s): ") + WX_TO_STD(range));
176  continue;
177  }
178 
179  // actually do the highlighting, finally!
180  GlobalMessenger()->AddHighlights(seq, from, to);
181  }
182  }
183 
184  // store messaged highlights in the cache
185  INFOMSG("Cached incoming highlights");
187 }
188 
190 {
191  if (dataIn.size() == 0) {
192  ADD_REPLY_ERROR("no file name given");
193  return;
194  }
195 
196  // default response
198  dataOut->erase();
199 
200  // give sequence and structure windows a chance to save data
201  if (structureWindow->glCanvas->structureSet) {
203  structureWindow->SaveDialog(true, false); // can't cancel
204  }
205 
206  wxString stripped(wxString(dataIn.c_str()).Strip(wxString::both));
207  if (!structureWindow->LoadData(stripped.c_str(), true, false))
208  ADD_REPLY_ERROR(string("Error loading file '") + WX_TO_STD(stripped) + "'");
209 }
210 
212 {
213  // default response
215  dataOut->erase();
216 
217  structureWindow->ProcessCommand(StructureWindow::MID_EXIT);
218 }
219 
220 END_SCOPE(Cn3D)
#define static
void ProcessCommand(const std::string &command, const std::string &dataIn, ncbi::MessageResponder::ReplyStatus *status, std::string *dataOut)
void SequenceWindowsSave(bool prompt)
Definition: messenger.cpp:183
bool RemoveAllHighlights(bool postRedraws)
Definition: messenger.cpp:393
void AddHighlights(const Sequence *sequence, unsigned int seqIndexFrom, unsigned int seqIndexTo)
Definition: messenger.cpp:248
void CacheHighlights(void)
Definition: messenger.cpp:412
unsigned int Length(void) const
#define TRACEMSG(stream)
Definition: cn3d_tools.hpp:83
#define INFOMSG(stream)
Definition: cn3d_tools.hpp:84
#define WX_TO_STD(wxstring)
Definition: cn3d_tools.hpp:285
#define ERRORMSG(stream)
Definition: cn3d_tools.hpp:86
USING_SCOPE(objects)
#define SPLIT_DATAIN_INTO_LINES
static void SplitString(const string &inStr, list< string > *outList)
USING_NCBI_SCOPE
Include a standard set of the NCBI C++ Toolkit most basic headers.
bool IdentifierToSeqId(const string &identifier, CRef< ncbi::objects::CSeq_id > &seqID)
#define END_SCOPE(ns)
End the previously defined scope.
Definition: ncbistl.hpp:75
#define BEGIN_SCOPE(ns)
Define a new scope.
Definition: ncbistl.hpp:72
static list< string > & Split(const CTempString str, const CTempString delim, list< string > &arr, TSplitFlags flags=0, vector< SIZE_TYPE > *token_pos=NULL)
Split a string using specified delimiters.
Definition: ncbistr.cpp:3457
static string LoadFile(CNcbiIstream &str)
int i
Messenger * GlobalMessenger(void)
Definition: messenger.cpp:73
range(_Ty, _Ty) -> range< _Ty >
const struct ncbi::grid::netcache::search::fields::SIZE size
const char * command
bool le(T x_, T y_, T round_)
Definition: njn_approx.hpp:84
#define IMPLEMENT_COMMAND_FUNCTION(name)
#define DECLARE_PARAMS
#define PROCESS_IF_COMMAND_IS(name)
#define ADD_REPLY_ERROR(msg)
#define const
Definition: zconf.h:230
Modified on Wed Feb 28 07:13:21 2024 by modify_doxy.py rev. 669887