- Fixed compilation problem on RedHat 7.3
[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, nxView)
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 EVT_MENU(XRCID("menuAlarmAck"), nxAlarmView::OnAlarmAck)
36 EVT_MENU(XRCID("menuAlarmTerminate"), nxAlarmView::OnAlarmTerminate)
37 EVT_MENU(XRCID("menuAlarmDelete"), nxAlarmView::OnAlarmDelete)
38 END_EVENT_TABLE()
39
40
41 //
42 // Constructor
43 //
44
45 nxAlarmView::nxAlarmView(wxWindow *parent, const TCHAR *context)
46 : nxView(parent)
47 {
48 wxConfigBase *cfg = wxConfig::Get();
49 wxString path = cfg->GetPath();
50
51 m_context = context;
52
53 cfg->SetPath(m_context);
54 cfg->Read(_T("AlarmView/SortMode"), &m_sortMode, 0);
55 cfg->Read(_T("AlarmView/SortDir"), &m_sortDir, -1);
56
57 m_wndListCtrl = new wxListView(this, wxID_LIST_CTRL, wxDefaultPosition, wxDefaultSize,
58 wxLC_REPORT | wxLC_HRULES | wxLC_VRULES);
59 m_wndListCtrl->InsertColumn(0, _T("Severity"), wxLIST_FORMAT_LEFT, 70);
60 m_wndListCtrl->InsertColumn(1, _T("State"), wxLIST_FORMAT_LEFT, 70);
61 m_wndListCtrl->InsertColumn(2, _T("Source"), wxLIST_FORMAT_LEFT, 120);
62 m_wndListCtrl->InsertColumn(3, _T("Message"), wxLIST_FORMAT_LEFT, 200);
63 m_wndListCtrl->InsertColumn(4, _T("Count"), wxLIST_FORMAT_LEFT, 40);
64 m_wndListCtrl->InsertColumn(5, _T("Created"), wxLIST_FORMAT_LEFT, 70);
65 m_wndListCtrl->InsertColumn(6, _T("Last Change"), wxLIST_FORMAT_LEFT, 70);
66 wxImageList *imgList = NXMCGetImageListCopy(IMAGE_LIST_STATUS_SMALL);
67 imgList->Add(wxXmlResource::Get()->LoadIcon(_T("icoSmallOutstanding")));
68 imgList->Add(wxXmlResource::Get()->LoadIcon(_T("icoSmallAcknowledged")));
69 imgList->Add(wxXmlResource::Get()->LoadIcon(_T("icoSmallTerminated")));
70 imgList->Add(wxXmlResource::Get()->LoadIcon(_T("icoSortUp")));
71 imgList->Add(wxXmlResource::Get()->LoadIcon(_T("icoSortDown")));
72 m_wndListCtrl->AssignImageList(imgList, wxIMAGE_LIST_SMALL);
73 NXMCLoadListCtrlColumns(cfg, *m_wndListCtrl, _T("AlarmView"));
74
75 cfg->SetPath(path);
76
77 NXMCEvtConnect(nxEVT_NXC_ALARM_CHANGE, wxCommandEventHandler(nxAlarmView::OnAlarmChange), this);
78 }
79
80
81 //
82 // Destructor
83 //
84
85 nxAlarmView::~nxAlarmView()
86 {
87 NXMCEvtDisconnect(nxEVT_NXC_ALARM_CHANGE, wxCommandEventHandler(nxAlarmView::OnAlarmChange), this);
88
89 wxConfigBase *cfg = wxConfig::Get();
90 wxString path = cfg->GetPath();
91 cfg->SetPath(m_context);
92 cfg->Write(_T("AlarmView/SortMode"), m_sortMode);
93 cfg->Write(_T("AlarmView/SortDir"), m_sortDir);
94 NXMCSaveListCtrlColumns(cfg, *m_wndListCtrl, _T("AlarmView"));
95 cfg->SetPath(path);
96 }
97
98
99 //
100 // Resize handler
101 //
102
103 void nxAlarmView::OnSize(wxSizeEvent &event)
104 {
105 wxSize size = GetClientSize();
106 m_wndListCtrl->SetSize(0, 0, size.x, size.y);
107 }
108
109
110 //
111 // Refresh view
112 //
113
114 void nxAlarmView::RefreshView()
115 {
116 nxAlarmList *list;
117 nxAlarmList::iterator it;
118
119 m_wndListCtrl->DeleteAllItems();
120 list = NXMCGetAlarmList();
121
122 for(it = list->begin(); it != list->end(); it++)
123 {
124 AddAlarm(it->second);
125 }
126
127 NXMCUnlockAlarmList();
128
129 SortAlarmList();
130 }
131
132
133 //
134 // Add alarm to view
135 //
136
137 void nxAlarmView::AddAlarm(NXC_ALARM *alarm)
138 {
139 long item;
140
141 item = m_wndListCtrl->InsertItem(0x7FFFFFFF, NXMCGetStatusTextSmall(alarm->nCurrentSeverity), alarm->nCurrentSeverity);
142 if (item != -1)
143 {
144 m_wndListCtrl->SetItemData(item, alarm->dwAlarmId);
145 UpdateAlarm(item, alarm);
146 }
147 }
148
149
150 //
151 // Update alarm in view
152 //
153
154 void nxAlarmView::UpdateAlarm(long item, NXC_ALARM *alarm)
155 {
156 NXC_OBJECT *object;
157 TCHAR temp[64];
158
159 m_wndListCtrl->SetItem(item, 0, NXMCGetStatusTextSmall(alarm->nCurrentSeverity), alarm->nCurrentSeverity);
160 m_wndListCtrl->SetItem(item, 1, NXMCGetAlarmStateName(alarm->nState), alarm->nState + STATUS_TESTING + 1);
161
162 object = NXCFindObjectById(NXMCGetSession(), alarm->dwSourceObject);
163 if (object != NULL)
164 {
165 m_wndListCtrl->SetItem(item, 2, object->szName);
166 }
167 else
168 {
169 m_wndListCtrl->SetItem(item, 2, _T("<unknown>"));
170 }
171
172 m_wndListCtrl->SetItem(item, 3, alarm->szMessage);
173
174 _stprintf(temp, _T("%d"), alarm->dwRepeatCount);
175 m_wndListCtrl->SetItem(item, 4, temp);
176
177 m_wndListCtrl->SetItem(item, 5, NXMCFormatTimeStamp(alarm->dwCreationTime, temp, TS_LONG_DATE_TIME));
178 m_wndListCtrl->SetItem(item, 6, NXMCFormatTimeStamp(alarm->dwLastChangeTime, temp, TS_LONG_DATE_TIME));
179 }
180
181
182 //
183 // Handler for right click on item
184 //
185
186 void nxAlarmView::OnListItemRightClick(wxListEvent &event)
187 {
188 wxMenu *menu;
189
190 if (!IsBusy())
191 {
192 menu = wxXmlResource::Get()->LoadMenu(_T("menuCtxAlarm"));
193 if (menu != NULL)
194 {
195 PopupMenu(menu);
196 delete menu;
197 }
198 }
199 }
200
201
202 //
203 // Alarm comparision callback
204 //
205
206 static nxAlarmList *s_alarmList;
207
208 static int wxCALLBACK CompareAlarms(long item1, long item2, long sortData)
209 {
210 long mode = sortData & 0x7FFF;
211 int rc;
212 nxAlarmList::iterator it1, it2;
213 NXC_OBJECT *obj1, *obj2;
214
215 it1 = s_alarmList->find(item1);
216 it2 = s_alarmList->find(item2);
217 if ((it1 == s_alarmList->end()) || (it2 == s_alarmList->end()))
218 {
219 wxLogDebug(_T("CompareAlarms: invalid iterator returned"));
220 return 0; // Shouldn't happen
221 }
222
223 switch(mode)
224 {
225 case 0: // Severity
226 rc = COMPARE_NUMBERS(it1->second->nCurrentSeverity, it2->second->nCurrentSeverity);
227 break;
228 case 1: // State
229 rc = COMPARE_NUMBERS(it1->second->nState, it2->second->nState);
230 break;
231 case 2: // Source
232 obj1 = NXCFindObjectById(NXMCGetSession(), it1->second->dwSourceObject);
233 obj2 = NXCFindObjectById(NXMCGetSession(), it2->second->dwSourceObject);
234 rc = _tcsicmp((obj1 != NULL) ? obj1->szName : _T("(null)"), (obj2 != NULL) ? obj2->szName : _T("(null)"));
235 break;
236 case 3: // Message
237 rc = _tcsicmp(it1->second->szMessage, it2->second->szMessage);
238 break;
239 case 4: // Count
240 rc = COMPARE_NUMBERS(it1->second->dwRepeatCount, it2->second->dwRepeatCount);
241 break;
242 case 5: // Created
243 rc = COMPARE_NUMBERS(it1->second->dwCreationTime, it2->second->dwCreationTime);
244 break;
245 case 6: // Last changed
246 rc = COMPARE_NUMBERS(it1->second->dwLastChangeTime, it2->second->dwLastChangeTime);
247 break;
248 default:
249 rc = 0;
250 break;
251 }
252
253 return (sortData & 0x8000) ? rc : -rc;
254 }
255
256
257 //
258 // Sort aarm list
259 //
260
261 void nxAlarmView::SortAlarmList()
262 {
263 s_alarmList = NXMCGetAlarmList();
264 m_wndListCtrl->SortItems(CompareAlarms, m_sortMode | ((m_sortDir == 1) ? 0x8000 : 0));
265 NXMCUnlockAlarmList();
266
267 // Mark sorting column
268 m_wndListCtrl->SetColumnImage(m_sortMode, STATUS_TESTING + ((m_sortDir == 1) ? 4 : 5));
269 }
270
271
272 //
273 // Handler for column click
274 //
275
276 void nxAlarmView::OnListColumnClick(wxListEvent &event)
277 {
278 m_wndListCtrl->ClearColumnImage(m_sortMode);
279
280 if (m_sortMode == event.GetColumn())
281 {
282 m_sortDir = -m_sortDir;
283 }
284 else
285 {
286 m_sortMode = event.GetColumn();
287 }
288 SortAlarmList();
289 }
290
291
292 //
293 // Handler for alarm change event
294 //
295
296 void nxAlarmView::OnAlarmChange(wxCommandEvent &event)
297 {
298 long item;
299
300 switch(event.GetInt())
301 {
302 case NX_NOTIFY_NEW_ALARM:
303 case NX_NOTIFY_ALARM_CHANGED:
304 item = m_wndListCtrl->FindItem(-1, ((NXC_ALARM *)event.GetClientData())->dwAlarmId);
305 if (item != -1)
306 {
307 UpdateAlarm(item, (NXC_ALARM *)event.GetClientData());
308 }
309 else
310 {
311 AddAlarm((NXC_ALARM *)event.GetClientData());
312 }
313 SortAlarmList();
314 break;
315 case NX_NOTIFY_ALARM_TERMINATED:
316 case NX_NOTIFY_ALARM_DELETED:
317 item = m_wndListCtrl->FindItem(-1, ((NXC_ALARM *)event.GetClientData())->dwAlarmId);
318 if (item != -1)
319 m_wndListCtrl->DeleteItem(item);
320 break;
321 }
322 event.Skip();
323 }
324
325
326 //
327 // Handler for acknowledge alarm menu
328 //
329
330 static DWORD AckAlarms(int count, DWORD *list)
331 {
332 int i;
333 DWORD rcc;
334 NXC_SESSION session = NXMCGetSession();
335
336 for(i = 0; i < count; i++)
337 {
338 rcc = NXCAcknowledgeAlarm(session, list[i]);
339 if (rcc != RCC_SUCCESS)
340 break;
341 }
342 delete list;
343 return rcc;
344 }
345
346 void nxAlarmView::OnAlarmAck(wxCommandEvent &event)
347 {
348 int i, count = m_wndListCtrl->GetSelectedItemCount();
349 DWORD *idList = new DWORD[count];
350 long item;
351
352 for(i = 0, item = -1; i < count; i++)
353 {
354 item = m_wndListCtrl->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
355 if (item == -1)
356 break;
357 idList[i] = m_wndListCtrl->GetItemData(item);
358 }
359 DoRequestArg2((void *)AckAlarms, count, CAST_FROM_POINTER(idList, wxUIntPtr));
360 }
361
362
363 //
364 // Handler for terminate alarm menu
365 //
366
367 static DWORD TerminateAlarms(int count, DWORD *list)
368 {
369 int i;
370 DWORD rcc;
371 NXC_SESSION session = NXMCGetSession();
372
373 for(i = 0; i < count; i++)
374 {
375 rcc = NXCTerminateAlarm(session, list[i]);
376 if (rcc != RCC_SUCCESS)
377 break;
378 }
379 delete list;
380 return rcc;
381 }
382
383 void nxAlarmView::OnAlarmTerminate(wxCommandEvent &event)
384 {
385 int i, count = m_wndListCtrl->GetSelectedItemCount();
386 DWORD *idList = new DWORD[count];
387 long item;
388
389 for(i = 0, item = -1; i < count; i++)
390 {
391 item = m_wndListCtrl->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
392 if (item == -1)
393 break;
394 idList[i] = m_wndListCtrl->GetItemData(item);
395 }
396 DoRequestArg2((void *)TerminateAlarms, count, CAST_FROM_POINTER(idList, wxUIntPtr));
397 }
398
399
400 //
401 // Handler for delete alarm menu
402 //
403
404 static DWORD DeleteAlarms(int count, DWORD *list)
405 {
406 int i;
407 DWORD rcc;
408 NXC_SESSION session = NXMCGetSession();
409
410 for(i = 0; i < count; i++)
411 {
412 rcc = NXCDeleteAlarm(session, list[i]);
413 if (rcc != RCC_SUCCESS)
414 break;
415 }
416 delete list;
417 return rcc;
418 }
419
420 void nxAlarmView::OnAlarmDelete(wxCommandEvent &event)
421 {
422 int i, count = m_wndListCtrl->GetSelectedItemCount();
423 DWORD *idList = new DWORD[count];
424 long item;
425
426 for(i = 0, item = -1; i < count; i++)
427 {
428 item = m_wndListCtrl->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
429 if (item == -1)
430 break;
431 idList[i] = m_wndListCtrl->GetItemData(item);
432 }
433 DoRequestArg2((void *)DeleteAlarms, count, CAST_FROM_POINTER(idList, wxUIntPtr));
434 }
435