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

Go to the SVN repository for this file.

1 /* $Id: error_listctrl.cpp 47479 2023-05-02 13:24:02Z ucko $
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: Andrea Asztalos
27  */
28 
29 
30 #include <ncbi_pch.hpp>
33 
35 #include <wx/imaglist.h>
36 #include <numeric>
37 
38 
41 
42 static const char* empty_xpm[] = {
43 "16 16 2 1",
44 " c None",
45 "X c Gray25",
46 " ",
47 " ",
48 " ",
49 " ",
50 " ",
51 " ",
52 " ",
53 " ",
54 " ",
55 " ",
56 " ",
57 " ",
58 " ",
59 " ",
60 " ",
61 " " };
62 
63 static const char* up_xpm[] = {
64 "16 16 2 1",
65 " c None",
66 "X c Gray25",
67 " ",
68 " ",
69 " ",
70 " ",
71 " ",
72 " ",
73 " X ",
74 " XXX ",
75 " XXXXX ",
76 " XXXXXXX ",
77 " ",
78 " ",
79 " ",
80 " ",
81 " ",
82 " " };
83 
84 static const char* down_xpm[] = {
85 "16 16 2 1",
86 " c None",
87 "X c Gray25",
88 " ",
89 " ",
90 " ",
91 " ",
92 " ",
93 " ",
94 " XXXXXXX ",
95 " XXXXX ",
96 " XXX ",
97 " X ",
98 " ",
99 " ",
100 " ",
101 " ",
102 " ",
103 " " };
104 
106 {
107  this->m_Data = other.m_Data;
108  this->m_Ascending = other.m_Ascending;
109  this->m_SortedColumn = other.m_SortedColumn;
110 
111  Finalize();
112 }
113 
115 {
116  this->m_Data = other.m_Data;
117  this->m_Ascending = other.m_Ascending;
118  this->m_SortedColumn = other.m_SortedColumn;
119 
120  Finalize();
121  return *this;
122 }
123 
125 {
126  m_OrderedIndices.clear();
127  m_OrderedIndices = vector<long>(m_Data.size());
128  iota(m_OrderedIndices.begin(), m_OrderedIndices.end(), 0);
129 }
130 
131 string CErrorData::GetDataByCol(long item, long column) const
132 {
133  if (size_t(item) >= m_Data.size())
134  return kEmptyStr;
135 
136  long index = m_OrderedIndices[item];
137  switch (column) {
138  case 1:
139  return m_Data[index].m_Severity;
140  case 2:
141  return m_Data[index].m_SeqId;
142  case 3:
143  return m_Data[index].m_Title;
144  case 4:
145  return m_Data[index].m_ErrMsg;
146  default:
147  return kEmptyStr;
148  }
149  _ASSERT(false);
150  return kEmptyStr;
151 }
152 
153 string CErrorData::GetItemText(long item) const
154 {
155  if (m_SortedColumn <= 0)
156  return kEmptyStr;
157 
158  return GetDataByCol(item, m_SortedColumn);
159 }
160 
161 void CErrorData::SortByColumn(long col, bool revert_direction)
162 {
163  static auto compare_fn = [](auto itemA, auto itemB, bool ascending) {
164  return ascending ? itemA < itemB : itemA > itemB;
165  };
166 
167  if (m_SortedColumn != col) {
168  m_SortedColumn = static_cast<int>(col);
169  m_Ascending = true;
170  } else if (revert_direction) {
172  }
173 
174  sort(m_OrderedIndices.begin(), m_OrderedIndices.end(), [col, this](long indexA, long indexB) {
175  auto itemA = m_Data[indexA];
176  auto itemB = m_Data[indexB];
177 
178  switch (col) {
179  case 1:
180  return compare_fn(itemA.m_Severity, itemB.m_Severity, m_Ascending);
181  case 2:
182  return compare_fn(itemA.m_SeqId, itemB.m_SeqId, m_Ascending);
183  case 3:
184  return compare_fn(itemA.m_Title, itemB.m_Title, m_Ascending);
185  case 4:
186  return compare_fn(itemA.m_ErrMsg, itemB.m_ErrMsg, m_Ascending);
187  default:
188  return false;
189  }
190  });
191 }
192 
193 CErrorListCtrl::CErrorListCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
194  : wxListCtrl(parent, id, pos, size, style)
195 {
196  {
197  // the color and the font of a selectable row (external version)
198  m_SelectAttr.SetTextColour(*wxBLUE);
199  wxFont font = m_SelectAttr.GetFont();
200  font.SetUnderlined(true);
201  m_SelectAttr.SetFont(font);
202  }
203 
204  wxInitAllImageHandlers();
205  static bool bitmap_registered = false;
206  if (!bitmap_registered)
207  {
209  provider->RegisterFileAlias(wxT("validate::edit"), wxT("pen.png"));
210  bitmap_registered = true;
211  }
212 
213  m_imageListSmall = new wxImageList(16, 16);
214 
215  m_imageListSmall->Add(wxBitmap(empty_xpm));
216  m_imageListSmall->Add(wxBitmap(down_xpm));
217  m_imageListSmall->Add(wxBitmap(up_xpm));
218  m_imageListSmall->Add(wxArtProvider::GetBitmap(wxT("validate::edit")));
219 
220  InsertColumn(0, _(" "), wxLIST_FORMAT_LEFT, 16);
221  InsertColumn(1, _(" Severity"), wxLIST_FORMAT_LEFT);
222  InsertColumn(2, _("Sequence"), wxLIST_FORMAT_LEFT);
223  InsertColumn(3, _("Error title"), wxLIST_FORMAT_LEFT);
224  InsertColumn(4, _("Message & Object Description"), wxLIST_FORMAT_LEFT, 750);
225  SetImageList(m_imageListSmall, wxIMAGE_LIST_SMALL);
226 
227  Bind(wxEVT_LIST_COL_CLICK, &CErrorListCtrl::OnColumnClicked, this);
228 }
229 
230 long CErrorListCtrl::GetActualIndex(long item) const
231 {
232  if (size_t(item) >= m_ListData->size())
233  return -1;
234 
235  return m_ListData->m_OrderedIndices[item];
236 }
237 
238 wxString CErrorListCtrl::OnGetItemText(long item, long column) const
239 {
240  return ToWxString(m_ListData->GetDataByCol(item, column));
241 }
242 
243 int CErrorListCtrl::OnGetItemImage(long item) const
244 {
245  if (size_t(item) >= m_ListData->size())
246  return -1;
247 
248  long index = m_ListData->m_OrderedIndices[item];
249  return m_ListData->m_Data[index].m_ImgIndex;
250 }
251 
252 wxListItemAttr* CErrorListCtrl::OnGetItemAttr(long item) const
253 {
254  if (size_t(item) >= m_ListData->size()) {
255  return nullptr; // to use the default parameters
256  }
257 
258  long index = m_ListData->m_OrderedIndices[item];
259  if (m_ListData->m_Data[index].m_Selectable) {
260  return const_cast<wxListItemAttr*>(&m_SelectAttr);
261  }
262  return nullptr;
263 }
264 
266 {
267  auto sorted_col = 0;
268  if (m_ListData) {
269  sorted_col = m_ListData->m_SortedColumn;
270  }
271  m_ListData = error_data;
272  if (sorted_col > 0) {
273  m_ListData->m_SortedColumn = sorted_col;
274  }
275 
276  SetItemCount(long(m_ListData->size()));
277 
278  if (GetItemCount() > 0) {
279  SetColumnWidth(0, wxLIST_AUTOSIZE_USEHEADER);
280  SetColumnWidth(1, wxLIST_AUTOSIZE_USEHEADER);
281  SetColumnWidth(2, wxLIST_AUTOSIZE);
282  SetColumnWidth(3, wxLIST_AUTOSIZE);
283  SetColumnWidth(4, wxLIST_AUTOSIZE);
284  }
285  else {
286  SetColumnWidth(0, wxLIST_AUTOSIZE_USEHEADER);
287  SetColumnWidth(1, wxLIST_AUTOSIZE_USEHEADER);
288  SetColumnWidth(2, wxLIST_AUTOSIZE_USEHEADER);
289  SetColumnWidth(3, wxLIST_AUTOSIZE_USEHEADER);
290  SetColumnWidth(4, wxLIST_AUTOSIZE_USEHEADER);
291  }
292 
293  if (m_ListData->m_SortedColumn > 0) {
295 
296  wxListItem item;
297  item.SetMask(wxLIST_MASK_IMAGE);
298  item.SetImage(m_ListData->m_Ascending ? 1 : 2);
299  SetColumn(m_ListData->m_SortedColumn, item);
300  }
301 
302  Refresh();
303 }
304 
305 string CErrorListCtrl::GetItemText(long item) const
306 {
307  return m_ListData->GetItemText(item);
308 }
309 
310 void CErrorListCtrl::OnColumnClicked(wxListEvent& event)
311 {
312  auto selected_index = x_GetSelectedIndex();
313  long selected_data_index;
314 
315  if (selected_index != -1) {
316  selected_data_index = m_ListData->m_OrderedIndices[selected_index];
317 
318  // deselect old index
319  SetItemState(selected_index, 0, wxLIST_STATE_SELECTED);
320  }
321 
322  auto sort_by_col = event.GetColumn();
323  auto sorted_col = m_ListData->m_SortedColumn;
324 
325  if (sorted_col != sort_by_col && sorted_col > 0) {
326  wxListItem item;
327  item.SetMask(wxLIST_MASK_IMAGE);
328  item.SetImage(0);
329  this->SetColumn(sorted_col, item);
330  }
331 
332  m_ListData->SortByColumn(sort_by_col, true);
333 
334  _ASSERT(sort_by_col == m_ListData->m_SortedColumn);
335 
336  if (m_ListData->m_SortedColumn > 0) {
337  wxListItem item;
338  item.SetMask(wxLIST_MASK_IMAGE);
339  item.SetImage(m_ListData->m_Ascending ? 1 : 2);
340  SetColumn(m_ListData->m_SortedColumn, item);
341  }
342  Refresh();
343 
344  if (selected_index != -1) {
345  auto index_to_select = x_FindIndexOfDataIndex(selected_data_index);
346  SetItemState(index_to_select, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
347  EnsureVisible(index_to_select);
348  }
349 }
350 
352 {
353  return GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
354 }
355 
356 long CErrorListCtrl::x_FindIndexOfDataIndex(long data_index) const
357 {
358  const auto& ordered_indices = m_ListData->m_OrderedIndices;
359  return find(ordered_indices.begin(), ordered_indices.end(), data_index) - ordered_indices.begin();
360 }
361 
362 
364 
vector< long > m_OrderedIndices
vector to store ordered indices
string GetDataByCol(long item, long column) const
TErrorData m_Data
CErrorData & operator=(const CErrorData &other)
string GetItemText(long item) const
size_t size() const
void SortByColumn(long col, bool revert_direction)
wxItemAttr m_SelectAttr
the item attribute for the selectable row
long x_FindIndexOfDataIndex(long data_index) const
virtual wxItemAttr * OnGetItemAttr(long item) const override
long x_GetSelectedIndex() const
virtual int OnGetItemImage(long item) const override
string GetItemText(long item) const
void SetData(CRef< CErrorData > error_data)
void OnColumnClicked(wxListEvent &event)
virtual wxString OnGetItemText(long item, long column) const override
CErrorListCtrl(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxLC_REPORT|wxLC_VIRTUAL)
CRef< CErrorData > m_ListData
wxImageList * m_imageListSmall
long GetActualIndex(long item) const
virtual void RegisterFileAlias(const wxArtID &anId, const wxArtClient &aClient, const wxSize &aSize, const wxString &aName, long aType=wxBITMAP_TYPE_ANY, int anIndex=-1)
#define _(proto)
Definition: ct_nlmzip_i.h:78
USING_SCOPE(objects)
static const char * empty_xpm[]
static const char * down_xpm[]
static const char * up_xpm[]
static const char * column
Definition: stats.c:23
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
#define kEmptyStr
Definition: ncbistr.hpp:123
#define wxT(x)
Definition: muParser.cpp:41
constexpr auto sort(_Init &&init)
const struct ncbi::grid::netcache::search::fields::SIZE size
#define _ASSERT
wxFileArtProvider * GetDefaultFileArtProvider()
Definition: wx_utils.cpp:334
wxString ToWxString(const string &s)
Definition: wx_utils.hpp:173
Modified on Tue May 28 05:48:54 2024 by modify_doxy.py rev. 669887