Alarm browser improved
[public/netxms.git] / src / client / console / plugins / AlarmBrowser / view.cpp
1 /*
2 ** NetXMS - Network Management System
3 ** Portable management console - Alarm Browser plugin
4 ** Copyright (C) 2007 Victor Kirhenshtein
5 **
6 ** This program is free software; you can redistribute it and/or modify
7 ** it under the terms of the GNU General Public License as published by
8 ** the Free Software Foundation; either version 2 of the License, or
9 ** (at your option) any later version.
10 **
11 ** This program is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ** GNU General Public License for more details.
15 **
16 ** You should have received a copy of the GNU General Public License
17 ** along with this program; if not, write to the Free Software
18 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 **
20 ** File: view.cpp
21 **
22 **/
23
24 #include "alarm_browser.h"
25
26
27 //
28 // Event table
29 //
30
31 BEGIN_EVENT_TABLE(nxAlarmView, wxWindow)
32 EVT_SIZE(nxAlarmView::OnSize)
33 EVT_LIST_ITEM_RIGHT_CLICK(wxID_LIST_CTRL, nxAlarmView::OnListItemRightClick)
34 EVT_LIST_COL_CLICK(wxID_LIST_CTRL, nxAlarmView::OnListColumnClick)
35 END_EVENT_TABLE()
36
37
38 //
39 // Constructor
40 //
41
42 nxAlarmView::nxAlarmView(wxWindow *parent, const TCHAR *context)
43 : wxWindow(parent, wxID_ANY)
44 {
45 wxConfigBase *cfg = wxConfig::Get();
46 wxString path = cfg->GetPath();
47
48 m_context = context;
49
50 cfg->SetPath(m_context);
51 cfg->Read(_T("AlarmView/SortMode"), &m_sortMode, 0);
52 cfg->Read(_T("AlarmView/SortDir"), &m_sortDir, -1);
53
54 m_wndListCtrl = new wxListView(this, wxID_LIST_CTRL, wxDefaultPosition, wxDefaultSize,
55 wxLC_REPORT | wxLC_HRULES | wxLC_VRULES);
56 m_wndListCtrl->InsertColumn(0, _T("Severity"), wxLIST_FORMAT_LEFT, 70);
57 m_wndListCtrl->InsertColumn(1, _T("State"), wxLIST_FORMAT_LEFT, 70);
58 m_wndListCtrl->InsertColumn(2, _T("Source"), wxLIST_FORMAT_LEFT, 120);
59 m_wndListCtrl->InsertColumn(3, _T("Message"), wxLIST_FORMAT_LEFT, 200);
60 m_wndListCtrl->InsertColumn(4, _T("Count"), wxLIST_FORMAT_LEFT, 40);
61 m_wndListCtrl->InsertColumn(5, _T("Created"), wxLIST_FORMAT_LEFT, 70);
62 m_wndListCtrl->InsertColumn(6, _T("Last Change"), wxLIST_FORMAT_LEFT, 70);
63 wxImageList *imgList = NXMCGetImageListCopy(IMAGE_LIST_STATUS_SMALL);
64 imgList->Add(wxXmlResource::Get()->LoadIcon(_T("icoSmallOutstanding")));
65 imgList->Add(wxXmlResource::Get()->LoadIcon(_T("icoSmallAcknowledged")));
66 imgList->Add(wxXmlResource::Get()->LoadIcon(_T("icoSmallTerminated")));
67 imgList->Add(wxXmlResource::Get()->LoadIcon(_T("icoSortUp")));
68 imgList->Add(wxXmlResource::Get()->LoadIcon(_T("icoSortDown")));
69 m_wndListCtrl->AssignImageList(imgList, wxIMAGE_LIST_SMALL);
70 NXMCLoadListCtrlColumns(cfg, *m_wndListCtrl, _T("AlarmView"));
71
72 cfg->SetPath(path);
73 }
74
75
76 //
77 // Destructor
78 //
79
80 nxAlarmView::~nxAlarmView()
81 {
82 wxConfigBase *cfg = wxConfig::Get();
83 wxString path = cfg->GetPath();
84
85 cfg->SetPath(m_context);
86 cfg->Write(_T("AlarmView/SortMode"), m_sortMode);
87 cfg->Write(_T("AlarmView/SortDir"), m_sortDir);
88 NXMCSaveListCtrlColumns(cfg, *m_wndListCtrl, _T("AlarmView"));
89 cfg->SetPath(path);
90 }
91
92
93 //
94 // Resize handler
95 //
96
97 void nxAlarmView::OnSize(wxSizeEvent &event)
98 {
99 wxSize size = GetClientSize();
100 m_wndListCtrl->SetSize(0, 0, size.x, size.y);
101 }
102
103
104 //
105 // Refresh view
106 //
107
108 void nxAlarmView::RefreshView()
109 {
110 nxAlarmList *list;
111 nxAlarmList::iterator it;
112
113 m_wndListCtrl->DeleteAllItems();
114 list = NXMCGetAlarmList();
115
116 for(it = list->begin(); it != list->end(); it++)
117 {
118 AddAlarm(it->second);
119 }
120
121 NXMCUnlockAlarmList();
122
123 SortAlarmList();
124 }
125
126
127 //
128 // Add alarm to view
129 //
130
131 void nxAlarmView::AddAlarm(NXC_ALARM *alarm)
132 {
133 long item;
134
135 item = m_wndListCtrl->InsertItem(0x7FFFFFFF, NXMCGetStatusTextSmall(alarm->nCurrentSeverity), alarm->nCurrentSeverity);
136 if (item != -1)
137 {
138 m_wndListCtrl->SetItemData(item, alarm->dwAlarmId);
139 UpdateAlarm(item, alarm);
140 }
141 }
142
143
144 //
145 // Update alarm in view
146 //
147
148 void nxAlarmView::UpdateAlarm(long item, NXC_ALARM *alarm)
149 {
150 NXC_OBJECT *object;
151 TCHAR temp[64];
152
153 m_wndListCtrl->SetItem(item, 0, NXMCGetStatusTextSmall(alarm->nCurrentSeverity), alarm->nCurrentSeverity);
154 m_wndListCtrl->SetItem(item, 1, NXMCGetAlarmStateName(alarm->nState), alarm->nState + STATUS_TESTING + 1);
155
156 object = NXCFindObjectById(NXMCGetSession(), alarm->dwSourceObject);
157 if (object != NULL)
158 {
159 m_wndListCtrl->SetItem(item, 2, object->szName);
160 }
161 else
162 {
163 m_wndListCtrl->SetItem(item, 2, _T("<unknown>"));
164 }
165
166 m_wndListCtrl->SetItem(item, 3, alarm->szMessage);
167
168 _stprintf(temp, _T("%d"), alarm->dwRepeatCount);
169 m_wndListCtrl->SetItem(item, 4, temp);
170
171 m_wndListCtrl->SetItem(item, 5, NXMCFormatTimeStamp(alarm->dwCreationTime, temp, TS_LONG_DATE_TIME));
172 m_wndListCtrl->SetItem(item, 6, NXMCFormatTimeStamp(alarm->dwLastChangeTime, temp, TS_LONG_DATE_TIME));
173 }
174
175
176 //
177 // Handler for right click on item
178 //
179
180 void nxAlarmView::OnListItemRightClick(wxListEvent &event)
181 {
182 wxMenu *menu;
183
184 menu = wxXmlResource::Get()->LoadMenu(_T("menuCtxAlarm"));
185 if (menu != NULL)
186 {
187 PopupMenu(menu);
188 delete menu;
189 }
190 }
191
192
193 //
194 // Alarm comparision callback
195 //
196
197 static nxAlarmList *s_alarmList;
198
199 static int wxCALLBACK CompareAlarms(long item1, long item2, long sortData)
200 {
201 long mode = sortData & 0x7FFF;
202 int rc;
203 nxAlarmList::iterator it1, it2;
204 NXC_OBJECT *obj1, *obj2;
205
206 it1 = s_alarmList->find(item1);
207 it2 = s_alarmList->find(item2);
208 if ((it1 == s_alarmList->end()) || (it2 == s_alarmList->end()))
209 {
210 wxLogWarning(_T("CompareAlarms: invalid iterator returned"));
211 return 0; // Shouldn't happen
212 }
213
214 switch(mode)
215 {
216 case 0: // Severity
217 rc = COMPARE_NUMBERS(it1->second->nCurrentSeverity, it2->second->nCurrentSeverity);
218 break;
219 case 1: // State
220 rc = COMPARE_NUMBERS(it1->second->nState, it2->second->nState);
221 break;
222 case 2: // Source
223 obj1 = NXCFindObjectById(NXMCGetSession(), it1->second->dwSourceObject);
224 obj2 = NXCFindObjectById(NXMCGetSession(), it2->second->dwSourceObject);
225 rc = _tcsicmp((obj1 != NULL) ? obj1->szName : _T("(null)"), (obj2 != NULL) ? obj2->szName : _T("(null)"));
226 break;
227 case 3: // Message
228 rc = _tcsicmp(it1->second->szMessage, it2->second->szMessage);
229 break;
230 case 4: // Count
231 rc = COMPARE_NUMBERS(it1->second->dwRepeatCount, it2->second->dwRepeatCount);
232 break;
233 case 5: // Created
234 rc = COMPARE_NUMBERS(it1->second->dwCreationTime, it2->second->dwCreationTime);
235 break;
236 case 6: // Last changed
237 rc = COMPARE_NUMBERS(it1->second->dwLastChangeTime, it2->second->dwLastChangeTime);
238 break;
239 default:
240 rc = 0;
241 break;
242 }
243
244 return (sortData & 0x8000) ? rc : -rc;
245 }
246
247
248 //
249 // Sort aarm list
250 //
251
252 void nxAlarmView::SortAlarmList()
253 {
254 s_alarmList = NXMCGetAlarmList();
255 m_wndListCtrl->SortItems(CompareAlarms, m_sortMode | ((m_sortDir == 1) ? 0x8000 : 0));
256 NXMCUnlockAlarmList();
257
258 // Mark sorting column
259 m_wndListCtrl->SetColumnImage(m_sortMode, STATUS_TESTING + ((m_sortDir == 1) ? 4 : 5));
260 }
261
262
263 //
264 // Handler for column click
265 //
266
267 void nxAlarmView::OnListColumnClick(wxListEvent &event)
268 {
269 m_wndListCtrl->ClearColumnImage(m_sortMode);
270
271 if (m_sortMode == event.GetColumn())
272 {
273 m_sortDir = -m_sortDir;
274 }
275 else
276 {
277 m_sortMode = event.GetColumn();
278 }
279 SortAlarmList();
280 }