NCBI C++ ToolKit
sel_list_model_impl.hpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #ifndef GUI_WIDGETS_ALN_MULTIPLE___SEL_LIST_MODEL_IMPL__HPP
2 #define GUI_WIDGETS_ALN_MULTIPLE___SEL_LIST_MODEL_IMPL__HPP
3 
4 /* $Id: sel_list_model_impl.hpp 19270 2009-05-13 18:18:16Z voronov $
5  * ===========================================================================
6  *
7  * PUBLIC DOMAIN NOTICE
8  * National Center for Biotechnology Information
9  *
10  * This software/database is a "United States Government Work" under the
11  * terms of the United States Copyright Act. It was written as part of
12  * the author's official duties as a United States Government employee and
13  * thus cannot be copyrighted. This software/database is freely available
14  * to the public for use. The National Library of Medicine and the U.S.
15  * Government have not placed any restriction on its use or reproduction.
16  *
17  * Although all reasonable efforts have been taken to ensure the accuracy
18  * and reliability of the software and data, the NLM and the U.S.
19  * Government do not and cannot warrant the performance or results that
20  * may be obtained by using this software or data. The NLM and the U.S.
21  * Government disclaim all warranties, express or implied, including
22  * warranties of performance, merchantability or fitness for any particular
23  * purpose.
24  *
25  * Please cite the author in any work or product based on this material.
26  *
27  * ===========================================================================
28  *
29  * Authors: Andrey Yazhuk
30  *
31  * File Description:
32  *
33  */
34 
35 
36 #include <corelib/ncbistl.hpp>
37 #include <corelib/ncbistd.hpp>
38 
40 
42 
43 ////////////////////////////////////////////////////////////////////////////////
44 /// CSelListModelImpl provides a defult implementation of ISelListModel.
45 ///
46 /// m_iFocusedItem and m_iAnchor item are not updated automatically.
47 template <class Item>
48 class CSelListModelImpl : public ISelListModel<Item>
49 {
50 public:
54 
55  typedef vector<TItem> TItemVector;
56 
57  /// related interfaces
58  ///
59 
62 
63  // ISelListModel interface implementation
64  virtual TIndex SLM_GetItemsCount() const;
65  virtual TItem SLM_GetItem(TIndex index) const;
66 
67  virtual TIndex SLM_GetFocusedItemIndex() const;
68  virtual bool SLM_IsItemSelected(TIndex index) const;
69  virtual TIndex SLM_GetSelectedCount() const;
70  virtual void SLM_GetSelectedIndices(TIndexVector& vIndices) const;
71  virtual void SLM_GetSelectedItems(TItemVector& items) const;
72 
73  virtual void SLM_FocusItem(TIndex index);
74 
75  virtual void SLM_SelectSingleItem(TIndex index);
76  virtual void SLM_InvertSingleItem(TIndex index);
77  virtual void SLM_SelectItems(const TIndexVector& vIndeces,
78  bool b_reset_others = false);
79  virtual void SLM_SelectAll(bool bSelect = true);
80  virtual void SLM_SelectTo(TIndex index);
81 
82  virtual void SLM_AddSLView(TSelListView* pView);
83  virtual void SLM_RemoveSLView(TSelListView* pView);
84 
85 protected:
87 
88  void SetItems(const TItemVector& vItems, bool b_update,
89  bool b_keep_selection = false);
90 
91  bool InsertItem(TIndex index, const TItem& item, bool b_update);
92  void InsertItems(const TItemVector& v_items, const TIndexVector& v_indices,
93  bool b_update);
94 
95  bool DeleteItem(TIndex index, bool bUpdate = true);
96  void DeleteItems(const TIndexVector& vIndices, bool b_update);
97  void DeleteAllItems();
98 
99 protected:
100  typedef pair<TItem, bool> TItemEntry; // bool for "Selected" state
101  typedef vector<TItemEntry> TEntryVector;
103  typedef list<TSelListView*> TViewList;
104 
105  virtual void x_SelectItem(TIndex index, bool b_sel) = 0;
106  virtual bool x_IsItemSelected(TIndex index) const = 0;
107 
108  virtual TIndex x_GetItemsCount() const = 0;
109  virtual TItem x_GetItem(TIndex index) const = 0;
110  virtual void x_SetEntries(const TEntryVector& v_entries) = 0;
111  virtual TIndex x_GetItemIndex(const TItem& item) = 0;
112 
113  /// inserts item, but does not updates all data structures
114  virtual void x_InsertItem(TIndex index, const TItemEntry& entry) = 0;
115  /// performs update after all items have been inserted
116  virtual void x_CompleteInsertion() = 0;
117 
118  /// mark item for deletion
119  virtual void x_MarkItemForErase(TIndex index) = 0;
120  /// deletes all marked items in a single pass, performs neccessary updates
121  virtual void x_EraseMarkedItems() = 0;
122 
123  virtual void x_ClearItems() = 0;
124 
125  /// TODO
126  void x_EraseItem(TIndex index)
127  {
128  // TODO
129  _ASSERT(false);
130  }
131 
132 protected:
133 
134  void x_Clear();
135  void x_GetSelectedItems(TIndexVector& vIndices);
136 
137  void x_ViewsUpdateItems(TIndexVector &vIndices);
138  void x_ViewsUpdateItemRange(int iStart, int iEnd);
139 
140 protected: // data members
144 
146 };
147 
148 
149 ////////////////////////////////////////////////////////////////////////////////
150 /// class CSelListModelImpl
151 template<class Item>
153 : m_SelectedCount(0),
154  m_iFocusedItem(-1),
155  m_iAnchorItem(-1)
156 {
157 }
158 
159 template<class Item>
161 {
162  return x_GetItemsCount();
163 }
164 
165 template<class Item>
167 {
168  return x_GetItem(index);
169 }
170 
171 template<class Item>
173 {
174  return m_iFocusedItem;
175 }
176 
177 template<class Item>
179 {
180  return x_IsItemSelected(index);
181 }
182 
183 template<class Item>
185 {
186  return m_SelectedCount;
187 }
188 
189 template<class Item>
191 {
192  int size = (int) x_GetItemsCount();
193  for( int i = 0; i < size; i++ ) {
194  if (x_IsItemSelected(i)) {
195  vIndices.push_back(i);
196  }
197  }
198 }
199 
200 template<class Item>
202 {
203  int size = x_GetItemsCount();
204  for( int i = 0; i < size; i++ ) {
205  if (x_IsItemSelected(i)) {
206  TItem item = x_GetItem(i);
207  items.push_back(item);
208  }
209  }
210 }
211 
212 template<class Item>
214 {
215  if (index != m_iFocusedItem) {
216  TIndexVector vUpdateItems;
217  vUpdateItems.push_back(m_iFocusedItem); // update old focus
218  m_iFocusedItem = index;
219  vUpdateItems.push_back(m_iFocusedItem); // update new one
220 
221  x_ViewsUpdateItems(vUpdateItems);
222  }
223 }
224 
225 template<class Item>
227 {
228  TIndexVector vPrevSel;
229  x_GetSelectedItems(vPrevSel);
230 
231  if(m_iFocusedItem != index) {
232  if(m_iFocusedItem >= 0 && ! x_IsItemSelected(m_iFocusedItem))
233  vPrevSel.push_back(m_iFocusedItem); // if it is not selected - we need update it separately
234  m_iFocusedItem = index;
235  }
236 
237  for(size_t i = 0; i < vPrevSel.size(); i++ ) { // reset selection
238  TIndex idx = vPrevSel[i];
239  x_SelectItem(idx, false);
240  }
241  if( index > -1) {
242  x_SelectItem(index, true);
243  vPrevSel.push_back(index);
244  m_iAnchorItem = index;
245  m_SelectedCount = 1;
246  } else m_SelectedCount = 0;
247 
248  x_ViewsUpdateItems(vPrevSel);
249 }
250 
251 
252 template<class Item>
254 {
255  TIndexVector vIndices;
256  if( index > -1) {
257  if(m_iFocusedItem != index) {
258  vIndices.push_back(m_iFocusedItem);
259  m_iFocusedItem = index;
260  }
261  bool b_old_sel = x_IsItemSelected(index);
262  x_SelectItem(index, ! b_old_sel);
263  vIndices.push_back(index);
264  m_iAnchorItem = index;
265  m_SelectedCount += b_old_sel ? -1 : 1;
266  } else m_SelectedCount = 0;
267 
268  x_ViewsUpdateItems(vIndices);
269 }
270 
271 
272 /// Select items with given indices. If "b_invert_others" == "true" - deselects
273 /// all other items.
274 template<class Item>
276  bool b_reset_others)
277 {
278  if(b_reset_others) {
279  size_t n_items = x_GetItemsCount();
280  vector<bool> v_sel(n_items, false);
281  TIndex count = 0;
282 
283  for( size_t i = 0; i < vIndices.size(); i++ ) {
284  if( ! v_sel[vIndices[i]]) { // to count correctly
285  v_sel[vIndices[i]] = true;
286  count++;
287  }
288  }
289  for( size_t j= 0; j < n_items; j++ ) {
290  x_SelectItem((int) j, v_sel[j]);
291  }
292 
293  m_SelectedCount = count;
294 
295  x_ViewsUpdateItemRange(0, (int) n_items - 1);
296  } else {
297  TIndexVector vUpdateIndices;
298 
299  ITERATE(typename TIndexVector, it, vIndices) {
300  if ( ! x_IsItemSelected(*it)) {
301  x_SelectItem(*it, true);
302  vUpdateIndices.push_back(*it);
303  }
304  }
305  m_SelectedCount += (int) vUpdateIndices.size();
306 
307  x_ViewsUpdateItems(vUpdateIndices);
308  }
309 }
310 
311 
312 template<class Item>
314 {
315  TIndex count = x_GetItemsCount();
316  for( TIndex i = 0; i < count; i++ ) {
317  x_SelectItem(i, b_select);
318  }
319  m_SelectedCount = b_select ? count : 0;
320 
321  if(count)
322  x_ViewsUpdateItemRange(0, count - 1);
323 }
324 
325 
326 template<class Item>
328 {
329  if(m_iAnchorItem<0)
330  m_iAnchorItem = 0;
331 
332  TIndex iStart = min(m_iAnchorItem, index);
333  TIndex iEnd = max(m_iAnchorItem, index);
334 
335  // reset old selection and select from iStart to iEnd
336  TIndexVector vUpdateIndices;
337  bool bPrevFocusedChanged = false;
338 
339  TIndex count = x_GetItemsCount();
340 
341  for( TIndex i = 0; i < count; i++ ) {
342  bool b_select = (i >= iStart && i <= iEnd);
343  if (x_IsItemSelected(i) != b_select)
344  {
345  x_SelectItem(i, b_select);
346  m_SelectedCount += b_select ? 1 : -1;
347  vUpdateIndices.push_back(i);
348  if(i == m_iFocusedItem)
349  bPrevFocusedChanged = true;
350  }
351  }
352  if(m_iFocusedItem != index)
353  {
354  if( ! bPrevFocusedChanged)
355  vUpdateIndices.push_back(m_iFocusedItem); // need to update
356  m_iFocusedItem = index;
357  }
358 
359  x_ViewsUpdateItems(vUpdateIndices);
360 }
361 
362 
363 template<class Item>
365 {
366  if( find(m_lsViews.begin(), m_lsViews.end(), pView) == m_lsViews.end()) {
367  m_lsViews.push_back(pView);
368  pView->SLV_SetModel(static_cast<TSelListModel*>(this));
369  }
370 }
371 
372 
373 template<class Item>
375 {
376  typename TViewList::iterator itView
377  = find( m_lsViews.begin(), m_lsViews.end(), pView);
378  if (itView != m_lsViews.end()) {
379  m_lsViews.erase(itView);
380  pView->SLV_SetModel(NULL);
381  }
382 }
383 
384 
385 template<class Item>
387  bool b_update, bool b_keep_selection)
388 {
389  size_t items_n = vItems.size();
390  TEntryVector v_entries(items_n);
391 
392  int n = x_GetItemsCount();
393  int n_sel = 0;
394  for( size_t i = 0; i < items_n; i++) {
395  v_entries[i].first = vItems[i];
396  bool b_sel = false;
397  if(b_keep_selection) {
398  TIndex index = x_GetItemIndex(vItems[i]);
399  b_sel = (index > -1 && index < n) ? x_IsItemSelected(index) : false;
400  }
401  v_entries[i].second = b_sel;
402  if(b_sel) {
403  n_sel++;
404  }
405  }
406 
407 
408  x_Clear();
409 
410  x_SetEntries(v_entries);
411  m_SelectedCount = n_sel;
412 
413  if(b_update) {
414  TIndex i_max = max(0, (int) items_n - 1);
415  x_ViewsUpdateItemRange(0, i_max);
416  }
417 }
418 
419 
420 template<class Item>
422  const TIndexVector& v_indices,
423  bool b_update)
424 {
425  size_t n_items = v_items.size();
426  _ASSERT(n_items == v_indices.size());
427 
428  TIndex i_min = x_GetItemsCount();
429  for( size_t i = 0; i < n_items; i++ ) {
430  TIndex ind = v_indices[i];
431  ind = min(ind, x_GetItemsCount());
432  x_InsertItem(ind, TItemEntry(v_items[i], false));
433 
434  i_min = min(i_min, ind);
435  }
436  x_CompleteInsertion();
437 
438  if(b_update) {
439  TIndex i_max = max(0, x_GetItemsCount() - 1);
440  x_ViewsUpdateItemRange(i_min, i_max);
441  }
442 }
443 
444 
445 template<class Item>
447  bool b_update)
448 {
449  if(index >= 0 && index <= x_GetItemsCount()) {
450  x_InsertItem(index, TItemEntry(item, false));
451  x_CompleteInsertion();
452 
453  if(b_update) {
454  TIndex i_max = max(0, x_GetItemsCount() - 1);
455  x_ViewsUpdateItemRange(index, i_max);
456  }
457  return true;
458  }
459  return false;
460 }
461 
462 
463 template<class Item>
465  bool bUpdate)
466 {
467  TIndex count = x_GetItemsCount();
468  TIndex min_del = count;
469 
470  ITERATE(typename TIndexVector, it, vIndices) {
471  TIndex index = *it;
472  if(index >= 0 && index < count) {
473  if(m_iFocusedItem == index)
474  m_iFocusedItem = -1;
475  if(m_iAnchorItem == index)
476  m_iAnchorItem = m_iFocusedItem;
477 
478  if(x_IsItemSelected(index)) //item selected
479  {
480  x_SelectItem(index, false);
481  m_SelectedCount--;
482  }
483 
484  x_MarkItemForErase(index);
485  min_del = min(index, count);
486  }
487  }
488  x_EraseMarkedItems();
489 
490  if(bUpdate && min_del < count) {
491  x_ViewsUpdateItemRange(min_del, count-1);
492  }
493 }
494 
495 
496 template<class Item>
497  bool CSelListModelImpl<Item>::DeleteItem(TIndex index, bool bUpdate)
498 {
499  TIndex count = x_GetItemsCount();
500  if(index >= 0 && index < count) {
501  if(m_iFocusedItem == index)
502  m_iFocusedItem = -1;
503  if(m_iAnchorItem == index)
504  m_iAnchorItem = m_iFocusedItem;
505 
506  if(x_IsItemSelected(index)) //item selected
507  m_SelectedCount--;
508 
509  x_EraseItem(index);
510 
511  if (bUpdate) {
512  TIndex i_max = max(0, count -1);
513  x_ViewsUpdateItemRange(0, i_max);
514  }
515  return true;
516  }
517  return false;
518 }
519 
520 
521 template<class Item>
523 {
524  x_Clear();
525  x_ViewsUpdateItemRange(0, -1);
526 }
527 
528 
529 template<class Item>
531 {
532  x_ClearItems();
533 
534  m_iFocusedItem = m_iAnchorItem = -1;
535  m_SelectedCount = 0;
536 }
537 
538 
539 template<class Item>
541 {
542  vIndices.reserve(m_SelectedCount);
543  TIndex count = x_GetItemsCount();
544  for( TIndex i = 0; i < count; i++ ) {
545  if(x_IsItemSelected(i))
546  vIndices.push_back(i);
547  }
548  _ASSERT(vIndices.size() == (size_t) m_SelectedCount);
549 }
550 
551 
552 template<class Item>
554 {
555  NON_CONST_ITERATE(typename TViewList, itView, m_lsViews)
556  (*itView)->SLV_UpdateItems(vIndices);
557 }
558 
559 
560 template<class Item>
562 {
563  NON_CONST_ITERATE(typename TViewList, itView, m_lsViews)
564  (*itView)->SLV_UpdateRange(iStart, iEnd);
565 }
566 
567 
569 
570 #endif // GUI_WIDGETS_ALN_MULTIPLE___SEL_LIST_MODEL_IMPL__HPP
CSelListModelImpl provides a defult implementation of ISelListModel.
void x_ViewsUpdateItemRange(int iStart, int iEnd)
ISelListModel< Item >::TIndexVector TIndexVector
virtual TItem x_GetItem(TIndex index) const =0
bool DeleteItem(TIndex index, bool bUpdate=true)
void InsertItems(const TItemVector &v_items, const TIndexVector &v_indices, bool b_update)
void x_GetSelectedItems(TIndexVector &vIndices)
virtual void SLM_GetSelectedItems(TItemVector &items) const
vector< TItem > TItemVector
ISelListModel< TItem > TSelListModel
void DeleteItems(const TIndexVector &vIndices, bool b_update)
bool InsertItem(TIndex index, const TItem &item, bool b_update)
list< TSelListView * > TViewList
virtual void x_CompleteInsertion()=0
performs update after all items have been inserted
virtual void SLM_SelectItems(const TIndexVector &vIndeces, bool b_reset_others=false)
Select items with given indices.
virtual bool x_IsItemSelected(TIndex index) const =0
virtual TIndex SLM_GetItemsCount() const
vector< TItemEntry > TEntryVector
virtual TIndex SLM_GetSelectedCount() const
virtual void SLM_RemoveSLView(TSelListView *pView)
virtual void SLM_SelectAll(bool bSelect=true)
ISelListModel< Item >::TItem TItem
virtual bool SLM_IsItemSelected(TIndex index) const
virtual void SLM_GetSelectedIndices(TIndexVector &vIndices) const
virtual TIndex x_GetItemIndex(const TItem &item)=0
virtual void x_SelectItem(TIndex index, bool b_sel)=0
virtual void SLM_FocusItem(TIndex index)
virtual TIndex x_GetItemsCount() const =0
virtual void x_SetEntries(const TEntryVector &v_entries)=0
virtual void SLM_InvertSingleItem(TIndex index)
virtual void SLM_AddSLView(TSelListView *pView)
ISelListModel< Item >::TIndex TIndex
virtual void x_ClearItems()=0
virtual void x_EraseMarkedItems()=0
deletes all marked items in a single pass, performs neccessary updates
virtual TIndex SLM_GetFocusedItemIndex() const
void x_EraseItem(TIndex index)
TODO.
virtual void SLM_SelectTo(TIndex index)
virtual void SLM_SelectSingleItem(TIndex index)
virtual void x_InsertItem(TIndex index, const TItemEntry &entry)=0
inserts item, but does not updates all data structures
virtual void x_MarkItemForErase(TIndex index)=0
mark item for deletion
ISelListView< TItem > TSelListView
related interfaces
void x_ViewsUpdateItems(TIndexVector &vIndices)
void SetItems(const TItemVector &vItems, bool b_update, bool b_keep_selection=false)
map< TItem, int > TItemToIndexMap
CSelListModelImpl()
class CSelListModelImpl
virtual TItem SLM_GetItem(TIndex index) const
pair< TItem, bool > TItemEntry
interface ISelListModel
Definition: list_mvc.hpp:45
vector< TIndex > TIndexVector
Definition: list_mvc.hpp:49
interface ISelListView
Definition: list_mvc.hpp:76
virtual void SLV_SetModel(TSelListModel *pModel)=0
Definition: map.hpp:338
Include a standard set of the NCBI C++ Toolkit most basic headers.
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
#define NON_CONST_ITERATE(Type, Var, Cont)
Non constant version of ITERATE macro.
Definition: ncbimisc.hpp:822
#define NULL
Definition: ncbistd.hpp:225
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
int i
yy_size_t n
const struct ncbi::grid::netcache::search::fields::SIZE size
The NCBI C++/STL use hints.
T max(T x_, T y_)
T min(T x_, T y_)
#define _ASSERT
Modified on Thu Dec 07 10:08:16 2023 by modify_doxy.py rev. 669887