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

Go to the SVN repository for this file.

1 /* $Id: menu_item.cpp 39417 2017-09-21 20:20:16Z katargir $
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: Andrey Yazhuk
27  *
28  */
29 
30 #include <ncbi_pch.hpp>
31 
32 #include <corelib/ncbistd.hpp>
33 
34 #include <gui/utils/menu_item.hpp>
35 
36 
38 
39 ////////////////////////////////////////////////////////////////////////////////
40 // CMenuItem
41 
43  : m_Type(eItem),
44  m_CommandID(0),
45  m_State(0),
46  m_ItemNode(this)
47 {
49 }
50 
51 CMenuItem::CMenuItem(const string& label, const string& image_alias)
52  : m_Type(eItem),
53  m_CommandID(0),
54  m_State(0),
55  m_ItemNode(this)
56 {
57  Init(eSubmenu, label, eCmdNone, image_alias);
58 }
59 
60 CMenuItem::CMenuItem(const string& label, TCmdID cmd, const string& image_alias,
61  const string& tooltip, int state)
62  : m_Type(eItem),
63  m_CommandID(0),
64  m_State(0),
65  m_ItemNode(this)
66 {
67  Init(eItem, label, cmd, image_alias, tooltip, state);
68 }
69 
71  const string& image_alias, const string& tooltip, int state)
72  : m_Type(eItem),
73  m_CommandID(0),
74  m_State(0),
75  m_ItemNode(this)
76 {
77  Init(type, label, cmd, image_alias, tooltip, state);
78 }
79 
80 ///copy contsructor - copes just attributes, not the subitems
82  : m_Type(eItem),
83  m_CommandID(0),
84  m_State(0),
85  m_ItemNode(this)
86 {
87  Init(item.m_Type, item.m_Label, item.m_CommandID, item.m_ImageAlias,
88  item.m_Tooltip, item.m_State);
89 }
90 
92 {
94 }
95 
96 void CMenuItem::Init(EType type, const string& label, TCmdID cmd,
97  const string& image_alias, const string& tooltip, int state)
98 {
99  m_Type = type;
100  m_Label = label;
101  m_CommandID = cmd;
102  m_ImageAlias = image_alias;
103  m_Tooltip = tooltip;
104  m_State = state;
105 }
106 
107 void CMenuItem::InitPopup(const string& label, const string& image_alias,
108  const string& tooltip)
109 {
110  Init(eSubmenu, label, eCmdNone, image_alias, tooltip);
111 }
112 
113 void CMenuItem::InitItem(const string& label, TCmdID cmd, const string& image_alias,
114  const string& tooltip, int state)
115 {
116  Init(eItem, label, cmd, image_alias, tooltip, state);
117 }
118 
120 {
121  Init(eSeparator);
122 }
123 
124 bool CMenuItem::Equal(const CMenuItem& item) const
125 {
126  return m_Type == item.m_Type && m_Label == item.m_Label
127  && m_CommandID == item.m_CommandID && m_ImageAlias == item.m_ImageAlias;
128 }
129 
131 {
132  CMenuItem* p_clone = new CMenuItem(*this);
133 
134  for(TChildItem_CI it = SubItemsBegin(); it != SubItemsEnd(); it++ ) {
135  CMenuItem* p_subitem = (*it)->GetValue();
136  p_clone->AddSubItem(p_subitem->Clone());
137  }
138 
139  return p_clone;
140 }
141 
143 {
144  return m_Type;
145 }
146 
148 {
149  m_Type = type;
150 }
151 
152 bool CMenuItem::IsItem() const
153 {
154  return m_Type == eItem;
155 }
156 
158 {
159  return m_Type == eSubmenu;
160 }
161 
163 {
164  return m_Type == eSeparator;
165 }
166 
167 const string& CMenuItem::GetLabel() const
168 {
169  return m_Label;
170 }
171 
172 void CMenuItem::SetLabel(const string& label)
173 {
174  m_Label = label;
175 }
176 
178 {
179  return m_CommandID;
180 }
181 
183 {
184  m_CommandID = cmd;
185 }
186 
188 {
189  return m_ImageAlias.size() > 0;
190 }
191 
192 const string& CMenuItem::GetImageAlias() const
193 {
194  return m_ImageAlias;
195 }
196 
197 void CMenuItem::SetImageAlias(const string& image_alias)
198 {
199  m_ImageAlias = image_alias;
200 }
201 
202 const string& CMenuItem::GetTooltip() const
203 {
204  return m_Tooltip;
205 }
206 
207 void CMenuItem::SetTooltip(const string& tooltip)
208 {
209  m_Tooltip = tooltip;
210 }
211 
213 {
214  return m_State;
215 }
216 
218 {
219  m_State = state;
220 }
221 
223 {
224  return (m_State & eDisabled) == 0;
225 }
226 
227 void CMenuItem::Enable(bool b_en)
228 {
229  x_SetState(eDisabled, ! b_en);
230 }
231 
233 {
234  return (m_State & eCheckItem) != 0;
235 }
236 
238 {
239  return (m_State & eCheckItem) && m_State & eSet;
240 }
241 
242 void CMenuItem::SetCheck(bool b_set)
243 {
245  x_SetState(eSet, b_set);
246 }
247 
249 {
250  return (m_State & eRadioItem) != 0;
251 }
252 
254 {
255  return m_State & eRadioItem && m_State & eSet;
256 }
257 
258 void CMenuItem::SelectRadio(bool b_set)
259 {
261  x_SetState(eSet, b_set);
262 }
263 
264 bool CMenuItem::IsValid() const
265 {
266  bool b_check = IsCheckType();
267  bool b_radio = IsRadioType();
268 
269  if(b_check && b_radio) {
270  return false; // cannot be both at the same time
271  } else if((b_check || b_radio) && ! IsItem()) {
272  return false;
273  } /*else if((m_State & eHideIfEmpty) && ! IsSubmenu()) {
274  return false;
275  }*/ else if(! IsSeparator() && m_Label.size()==0) {
276  return false; // label must not be empty
277  }
278  return true;
279 }
280 
281 static const char* kCannotMerge = "CMenuItem::Merge() cannot merge item ";
282 
283 /// Menu Item trees are merged based on item's labels. Labels specify unique path
284 /// to an item (similarly to paths in file systems).
285 void CMenuItem::Merge(const CMenuItem& item)
286 {
287  // this and "item" must be submenus with the same label
288  if(GetLabel() == item.GetLabel()) {
289  if(IsSubmenu() && item.IsSubmenu()) {
290  // iterating subitems of the given menu
291  bool named_group = false;
292  TChildItem_I grp_begin = SubItemsBegin();
293  TChildItem_I grp_end = SubItemsEnd();
294 
295  for( TChildItem_CI it = item.SubItemsBegin(); it != item.SubItemsEnd(); it++ ) {
296  const CMenuItem* sub_item = (*it)->GetValue();
297  const string& label = sub_item->GetLabel();
298 
299  if(sub_item->IsSeparator()) {
300  // separator indicates end of the current group and
301  // beginning of a new one
302  named_group = ! label.empty();
303  if(named_group) {
304  // find this group in this item
305  grp_begin = FindSubItem(eSeparator, label);
306  if(grp_begin != SubItemsEnd()) {
307  // find the end of the group
308  grp_begin++;
309  for( grp_end = grp_begin; grp_end != SubItemsEnd(); ++grp_end) {
310  const CMenuItem* it_item = (*grp_end)->GetValue();
311  if(it_item->IsSeparator()) {
312  break;
313  }
314  }
315  } else {
316  //the group does not exist - create a new one
318  grp_begin = grp_end = SubItemsEnd();
319  }
320  } else {
321  grp_begin = SubItemsBegin();
322  grp_end = SubItemsEnd();
323  }
324  } else {
325  // not a separator - item that can be merged
326  // find candidate within a group
327  TChildItem_I it_target = x_FindSubItem(grp_begin, grp_end, label, named_group);
328  if(it_target == grp_end) {
329  // this is a new item - add it
330  if(named_group) {
331  InsertSubItem(it_target, sub_item->Clone());
332  } else {
333  // may need to insert an unnamed separator
334  x_InsertInUnnamedGroup(*sub_item->Clone());
335  }
336  } else {
337  CMenuItem* target_sub_item = (*it_target)->GetValue();
338  x_MergeItems(*target_sub_item, *sub_item);
339  }
340  }
341  } //for
342 
343  } else {
344  ERR_POST(kCannotMerge << item.GetLabel() << " into " << GetLabel()
345  << ", because they are not submenus.");
346  }
347  } else {
348  ERR_POST(kCannotMerge << item.GetLabel() << " into " << GetLabel()
349  << ", because they have different labels.");
350  }
351 }
352 
353 
354 // merge new_item into the target
355 void CMenuItem::x_MergeItems(CMenuItem& target, const CMenuItem& new_item)
356 {
357  if(target.IsSubmenu()) {
358  // submenu - merge recursively
359  target.Merge(new_item);
360  } else if(target.IsItem()) {
361  // command item
362  string s_error;
363  if(! new_item.IsItem()) {
364  s_error = ", because it is not a command item.";
365  } else if(target.GetCommand() != new_item.GetCommand()) {
366  s_error = ", because they have different commands.";
367  }
368  if(s_error.size()) {
369  ERR_POST(kCannotMerge << new_item.GetLabel() << " into "
370  << target.GetLabel() << s_error);
371  }
372  // else, do nothing, because new_item is identical to target
373  }
374 }
375 
376 
379  const string& label, bool skip_named_groups)
380 {
381  if(skip_named_groups) {
382  bool named_group = false;
383  for(TChildItem_I it = it_begin; it != it_end; ++it ) {
384  const CMenuItem* sub_item = (*it)->GetValue();
385  const string& s = sub_item->GetLabel();
386 
387  if(sub_item->IsSeparator()) {
388  named_group = ! s.empty();
389  } else if( ! (named_group && skip_named_groups) && (s == label)) {
390  return it;
391  }
392  }
393  } else {
394  // assume that iterators
395  for(TChildItem_I it = it_begin; it != it_end; ++it ) {
396  const CMenuItem* sub_item = (*it)->GetValue();
397  const string& s = sub_item->GetLabel();
398 
399  if(s == label)
400  return it;
401  }
402  }
403  return it_end;
404 }
405 
406 
408 {
409  bool named = false;
410  // find the last separator in the menu
412  it != m_ItemNode.SubNodeREnd(); ++it) {
413  const CMenuItem* it_item = (*it)->GetValue();
414  if(it_item->IsSeparator()) {
415  named = ! it_item->GetLabel().empty();
416  break;
417  }
418  }
419 
420  if(named) {
421  AddSeparator(); // add an unnamed separator to terminate the previous group
422  }
423  AddSubItem(&item);
424 }
425 
426 
428 {
429  TItemNode* parent_node = m_ItemNode.GetParent();
430  return parent_node ? parent_node->GetValue() : NULL;
431 }
432 
433 const CMenuItem* CMenuItem::GetParent() const
434 {
435  const TItemNode* parent_node = m_ItemNode.GetParent();
436  return parent_node ? parent_node->GetValue() : NULL;
437 }
438 
440 {
441  _ASSERT(IsSubmenu());
442  if(item) {
443  TItemNode* node = & item->m_ItemNode;
444  m_ItemNode.AddNode(node);
445  }
446  return item;
447 }
448 
449 
451 {
453  it != m_ItemNode.SubNodeEnd(); ) {
454  TItemNode::TNodeList_I it2 = it++;
455  TItemNode* node = m_ItemNode.DetachNode(*it2);
456  delete node->GetValue();
457  }
458 }
459 
460 
462 {
463  CMenuItem* item = new CMenuItem();
464  return AddSubItem(item);
465 }
466 
467 
469 {
470  CMenuItem* item = new CMenuItem(eSeparator, label);
471  return AddSubItem(item);
472 }
473 
474 
475 CMenuItem* CMenuItem::AddSubMenu(const string& label, const string& image_alias)
476 {
477  CMenuItem* item = new CMenuItem(label, image_alias);
478  return AddSubItem(item);
479 }
480 
482  const string& image_alias, const string& tooltip,
483  int state)
484 {
485  CMenuItem* item = new CMenuItem(label, cmd, image_alias, tooltip, state);
486  return AddSubItem(item);
487 }
488 
489 
491 {
492  _ASSERT(IsSubmenu());
493  if(item) {
494  TItemNode* node = & item->m_ItemNode;
495  m_ItemNode.InsertNode(it, node);
496  }
497  return item;
498 }
499 
500 
502 {
503  CMenuItem* node = (*it)->GetValue();
505  delete node;
506 }
507 
508 
510 {
512 }
513 
515 {
516  return m_ItemNode.SubNodeBegin();
517 }
518 
520 {
521  return m_ItemNode.SubNodeEnd();
522 }
523 
525 {
526  return m_ItemNode.SubNodeBegin();
527 }
528 
530 {
531  return m_ItemNode.SubNodeEnd();
532 }
533 
535 {
536  for(TChildItem_I it = SubItemsBegin(); it != SubItemsEnd(); ++it) {
537  CMenuItem* curr = (*it)->GetValue();
538  if(curr->Equal(item))
539  return curr;
540  }
541  return NULL;
542 }
543 
545 {
546  for(TChildItem_CI it = SubItemsBegin(); it != SubItemsEnd(); ++it) {
547  const CMenuItem* curr = (*it)->GetValue();
548  if(curr->Equal(item))
549  return curr;
550  }
551  return NULL;
552 }
553 
555 {
556  for(TChildItem_I it = SubItemsBegin(); it != SubItemsEnd(); ++it) {
557  if((*it)->GetValue() == &item)
558  return it;
559  }
560  return SubItemsEnd();
561 }
562 
564 {
565  for(TChildItem_CI it = SubItemsBegin(); it != SubItemsEnd(); ++it) {
566  if((*it)->GetValue() == &item)
567  return it;
568  }
569  return SubItemsEnd();
570 }
571 
573 {
574  for(TChildItem_I it = SubItemsBegin(); it != SubItemsEnd(); ++it) {
575  if((*it)->GetValue()->GetLabel() == label)
576  return it;
577  }
578  return SubItemsEnd();
579 }
580 
582 {
583  for(TChildItem_CI it = SubItemsBegin(); it != SubItemsEnd(); ++it) {
584  if((*it)->GetValue()->GetLabel() == label)
585  return it;
586  }
587  return SubItemsEnd();
588 }
589 
590 
592 {
593  for(TChildItem_I it = SubItemsBegin(); it != SubItemsEnd(); ++it) {
594  const CMenuItem* item = (*it)->GetValue();
595  if(item->GetType() == type && item->GetLabel() == label)
596  return it;
597  }
598  return SubItemsEnd();
599 }
600 
601 
603 {
604  for(TChildItem_CI it = SubItemsBegin(); it != SubItemsEnd(); ++it) {
605  const CMenuItem* item = (*it)->GetValue();
606  if(item->GetType() == type && item->GetLabel() == label)
607  return it;
608  }
609  return SubItemsEnd();
610 }
611 
612 ////////////////////////////////////////////////////////////////////////////////
613 /// creates hierarchy of CMenuItem objects from the array of SMenuItemRec descriptors
615 {
616  if(items) {
617  CMenuItem* root = NULL;
618  vector<CMenuItem*> path;
619  const SMenuItemRec* p_rec = items;
620 
621  while(p_rec) {
622  CMenuItem* item = NULL;
623 
624  if(p_rec->IsSubMenu()) {
625  // create Submenu and add to path
626  item = new CMenuItem(p_rec->m_Label, p_rec->m_ImageAlias);
627  if(path.size()) {
628  path.back()->AddSubItem(item);
629  } else {
630  root = item;
631  }
632  path.push_back(item);
633  } else if(p_rec->IsSubMenuEnd()) {
634  //end current submenu and eject it from path
635  path.pop_back();
636  _ASSERT(! path.empty());
637  } else if(p_rec->IsMenuEnd()) {
638  path.pop_back();
639  _ASSERT(path.empty()); // all submenus were closed
640  return root;
641  } else if(p_rec->m_Type == CMenuItem::eItem) {
642  // add command item
643  item = new CMenuItem(p_rec->m_Label, p_rec->m_CommandID,
644  p_rec->m_ImageAlias, p_rec->m_Tooltip,
645  p_rec->m_State);
646  path.back()->AddSubItem(item);
647  } else if(p_rec->m_Type == CMenuItem::eSeparator) {
648  // add separator
649  item = new CMenuItem(CMenuItem::eSeparator, p_rec->m_Label);
650  path.back()->AddSubItem(item);
651  } else {
652  _ASSERT(false);
653  }
654  p_rec++;
655  }
656  }
657  return NULL;
658 }
659 
660 
661 
CMenuItem - represents a menu items in IMenu-style menus.
Definition: menu_item.hpp:53
Include a standard set of the NCBI C++ Toolkit most basic headers.
static CS_COMMAND * cmd
Definition: ct_dynamic.c:26
static int type
Definition: getdata.c:31
#define NULL
Definition: ncbistd.hpp:225
#define ERR_POST(message)
Error posting with file, line number information but without error codes.
Definition: ncbidiag.hpp:186
TItemNode m_ItemNode
Definition: menu_item.hpp:223
bool IsRadioType() const
Definition: menu_item.cpp:248
CMenuItem * AddSubItem(CMenuItem *item)
Definition: menu_item.cpp:439
bool IsMenuEnd() const
Definition: menu_item.hpp:245
CMenuItem * FindEqualSubItem(const CMenuItem &item)
Definition: menu_item.cpp:534
void RemoveItem(TChildItem_I it)
Definition: menu_item.cpp:501
bool IsSubmenuEmpty()
Definition: menu_item.cpp:509
const char * m_Label
Definition: menu_item.hpp:231
virtual ~CMenuItem()
Definition: menu_item.cpp:91
CMenuItem * Clone() const
clones item and its subitems
Definition: menu_item.cpp:130
TChildItem_I FindSubItem(const CMenuItem &item)
Definition: menu_item.cpp:554
bool IsItem() const
Definition: menu_item.cpp:152
void InitItem(const string &label, TCmdID cmd, const string &image_alias="", const string &tooltip="", int state=eDefault)
Definition: menu_item.cpp:113
EType m_Type
Definition: menu_item.hpp:216
bool IsCheckType() const
Definition: menu_item.cpp:232
void Init(EType type, const string &label="", TCmdID cmd=eCmdNone, const string &image_alias="", const string &tooltip="", int state=eDefault)
Definition: menu_item.cpp:96
CMenuItem * AddSeparator()
Adds Separator.
Definition: menu_item.cpp:461
void x_MergeItems(CMenuItem &target, const CMenuItem &new_item)
Definition: menu_item.cpp:355
bool IsSeparator() const
Definition: menu_item.cpp:162
void DestroyAllSubNodes()
Definition: menu_item.cpp:450
bool HasImage() const
Definition: menu_item.cpp:187
const char * m_ImageAlias
Definition: menu_item.hpp:233
void SelectRadio(bool b_set)
Definition: menu_item.cpp:258
TItemNode::TNodeList_CI TChildItem_CI
Definition: menu_item.hpp:150
bool IsSubMenuEnd() const
Definition: menu_item.hpp:241
void SetState(int state)
Definition: menu_item.cpp:217
void Enable(bool b_en)
Definition: menu_item.cpp:227
TChildItem_I SubItemsBegin()
Definition: menu_item.cpp:514
bool IsValid() const
Definition: menu_item.cpp:264
bool Equal(const CMenuItem &item) const
Definition: menu_item.cpp:124
void SetImageAlias(const string &image_alias)
Definition: menu_item.cpp:197
TChildItem_I SubItemsEnd()
Definition: menu_item.cpp:519
bool IsSubmenu() const
Definition: menu_item.cpp:157
bool IsRadioSelected() const
Definition: menu_item.cpp:253
const string & GetImageAlias() const
Definition: menu_item.cpp:192
void SetCheck(bool b_set)
Definition: menu_item.cpp:242
TChildItem_I x_FindSubItem(TChildItem_I it_begin, TChildItem_I it_end, const string &label, bool skip_named_groups)
Definition: menu_item.cpp:378
CMenuItem * AddSubMenu(const string &Label, const string &image_alias="")
it is recommended that labels start with '-'
Definition: menu_item.cpp:475
const string & GetLabel() const
Definition: menu_item.cpp:167
EType GetType() const
Definition: menu_item.cpp:142
const char * m_Tooltip
Definition: menu_item.hpp:234
void Merge(const CMenuItem &item)
merges menu tree represented by "item" into menu tree represented by "this"
Definition: menu_item.cpp:285
CMenuItem * GetParent()
Definition: menu_item.cpp:427
int GetState() const
Definition: menu_item.cpp:212
void x_InsertInUnnamedGroup(CMenuItem &item)
Definition: menu_item.cpp:407
string m_Tooltip
Definition: menu_item.hpp:220
TItemNode::TNodeList_I TChildItem_I
Definition: menu_item.hpp:149
void SetCommand(TCmdID cmd)
Definition: menu_item.cpp:182
bool IsSubMenu() const
Definition: menu_item.hpp:237
CTreeNode< CMenuItem * > TItemNode
Definition: menu_item.hpp:70
string m_ImageAlias
Definition: menu_item.hpp:219
TCmdID m_CommandID
Definition: menu_item.hpp:218
void SetTooltip(const string &tooltip)
Definition: menu_item.cpp:207
bool IsEnabled() const
Definition: menu_item.cpp:222
CMenuItem * CreateMenuItems(const SMenuItemRec *items)
creates hierarchy of CMenuItem objects from the array of SMenuItemRec descriptors
Definition: menu_item.cpp:614
void InitPopup(const string &label, const string &image_alias="", const string &tooltip="")
Definition: menu_item.cpp:107
string m_Label
Definition: menu_item.hpp:217
TCmdID m_CommandID
Definition: menu_item.hpp:232
void InitSeparator()
Definition: menu_item.cpp:119
void SetType(EType type)
Definition: menu_item.cpp:147
void SetLabel(const string &label)
Definition: menu_item.cpp:172
CMenuItem()
creates a separator item
Definition: menu_item.cpp:42
CMenuItem * InsertSubItem(TChildItem_I it, CMenuItem *item)
Definition: menu_item.cpp:490
EType
Type of menu item.
Definition: menu_item.hpp:56
const TCmdID & GetCommand() const
Definition: menu_item.cpp:177
void x_SetState(int mask, bool b_en)
Definition: menu_item.hpp:202
bool IsChecked() const
Definition: menu_item.cpp:237
int TCmdID
const string & GetTooltip() const
Definition: menu_item.cpp:202
@ eCmdNone
not a valid command
Definition: command.hpp:65
@ eRadioItem
"check-box" item
Definition: menu_item.hpp:66
@ eSet
"radio" item
Definition: menu_item.hpp:67
@ eCheckItem
item is disabled (visible but inactive)
Definition: menu_item.hpp:65
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
TNodeList::iterator TNodeList_I
Definition: ncbi_tree.hpp:109
TTreeType * DetachNode(TTreeType *subnode)
Remove the subtree from the tree without destroying it.
Definition: ncbi_tree.hpp:720
TNodeList_CRI SubNodeREnd(void) const
Return last const reverse iterator on subnode list.
Definition: ncbi_tree.hpp:178
TNodeList::reverse_iterator TNodeList_RI
Definition: ncbi_tree.hpp:111
TNodeList_CRI SubNodeRBegin(void) const
Return first const reverse iterator on subnode list.
Definition: ncbi_tree.hpp:172
TNodeList_CI SubNodeBegin(void) const
Return first const iterator on subnode list.
Definition: ncbi_tree.hpp:160
void AddNode(TTreeType *subnode)
Add new subnode.
Definition: ncbi_tree.hpp:743
TNodeList_CI SubNodeEnd(void) const
Return last const iterator on subnode list.
Definition: ncbi_tree.hpp:166
void InsertNode(TNodeList_I it, TTreeType *subnode)
Insert new subnode before the specified location in the subnode list.
Definition: ncbi_tree.hpp:773
const TValue & GetValue(void) const
Return node's value.
Definition: ncbi_tree.hpp:184
const TTreeType * GetParent(void) const
Get node's parent.
Definition: ncbi_tree.hpp:139
static const char label[]
static const char * kCannotMerge
Definition: menu_item.cpp:281
SMenuItemRec.
Definition: menu_item.hpp:229
Definition: type.c:6
#define _ASSERT
Modified on Fri Sep 20 14:57:45 2024 by modify_doxy.py rev. 669887