Console compiles on UNIX with UNICODE
[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_CONTEXT_MENU(nxAlarmView::OnContextMenu)
36 EVT_MENU(XRCID("menuAlarmAck"), nxAlarmView::OnAlarmAck)
37 EVT_UPDATE_UI(XRCID("menuAlarmAck"), nxAlarmView::OnUpdateAlarmAck)
38 EVT_MENU(XRCID("menuAlarmTerminate"), nxAlarmView::OnAlarmTerminate)
39 EVT_UPDATE_UI(XRCID("menuAlarmTerminate"), nxAlarmView::OnUpdateAlarmTerminate)
40 EVT_MENU(XRCID("menuAlarmDelete"), nxAlarmView::OnAlarmDelete)
41 EVT_UPDATE_UI(XRCID("menuAlarmDelete"), nxAlarmView::OnUpdateAlarmDelete)
42 EVT_MENU(XRCID("menuAlarmIncreaseFont"), nxAlarmView::OnAlarmIncreaseFont)
43 EVT_MENU(XRCID("menuAlarmDecreaseFont"), nxAlarmView::OnAlarmDecreaseFont)
44 END_EVENT_TABLE()
45
46
47 //
48 // Constructor
49 //
50
51 nxAlarmView::nxAlarmView(wxWindow *parent, const TCHAR *context, NXC_OBJECT *object)
52 : nxView(parent)
53 {
54 int fontSize;
55
56 wxConfigBase *cfg = wxConfig::Get();
57 wxString path = cfg->GetPath();
58
59 m_context = context;
60 m_object = object;
61
62 cfg->SetPath(m_context);
63 cfg->Read(_T("AlarmView/SortMode"), &m_sortMode, 0);
64 cfg->Read(_T("AlarmView/SortDir"), &m_sortDir, -1);
65 cfg->Read(_T("AlarmView/FontSize"), &fontSize, -1);
66
67 m_wndListCtrl = new wxListView(this, wxID_LIST_CTRL, wxDefaultPosition, wxDefaultSize,
68 wxLC_REPORT | wxLC_HRULES | wxLC_VRULES);
69 m_wndListCtrl->InsertColumn(0, _T("Severity"), wxLIST_FORMAT_LEFT, 70);
70 m_wndListCtrl->InsertColumn(1, _T("State"), wxLIST_FORMAT_LEFT, 70);
71 m_wndListCtrl->InsertColumn(2, _T("Source"), wxLIST_FORMAT_LEFT, 120);
72 m_wndListCtrl->InsertColumn(3, _T("Message"), wxLIST_FORMAT_LEFT, 200);
73 m_wndListCtrl->InsertColumn(4, _T("Count"), wxLIST_FORMAT_LEFT, 40);
74 m_wndListCtrl->InsertColumn(5, _T("Created"), wxLIST_FORMAT_LEFT, 70);
75 m_wndListCtrl->InsertColumn(6, _T("Last Change"), wxLIST_FORMAT_LEFT, 70);
76 wxImageList *imgList = NXMCGetImageListCopy(IMAGE_LIST_STATUS_SMALL);
77 imgList->Add(wxXmlResource::Get()->LoadIcon(_T("icoSmallOutstanding")));
78 imgList->Add(wxXmlResource::Get()->LoadIcon(_T("icoSmallAcknowledged")));
79 imgList->Add(wxXmlResource::Get()->LoadIcon(_T("icoSmallTerminated")));
80 imgList->Add(wxXmlResource::Get()->LoadIcon(_T("icoSortUp")));
81 imgList->Add(wxXmlResource::Get()->LoadIcon(_T("icoSortDown")));
82 m_wndListCtrl->AssignImageList(imgList, wxIMAGE_LIST_SMALL);
83 NXMCLoadListCtrlColumns(cfg, *m_wndListCtrl, _T("AlarmView"));
84
85 if (fontSize != -1)
86 {
87 wxFont font;
88
89 font = m_wndListCtrl->GetFont();
90 font.SetPointSize(fontSize);
91 m_wndListCtrl->SetFont(font);
92 }
93
94 cfg->SetPath(path);
95
96 SetIcon(wxXmlResource::Get()->LoadIcon(_T("icoAlarmView")));
97
98 NXMCEvtConnect(nxEVT_NXC_ALARM_CHANGE, wxCommandEventHandler(nxAlarmView::OnAlarmChange), this);
99 }
100
101
102 //
103 // Destructor
104 //
105
106 nxAlarmView::~nxAlarmView()
107 {
108 NXMCEvtDisconnect(nxEVT_NXC_ALARM_CHANGE, wxCommandEventHandler(nxAlarmView::OnAlarmChange), this);
109
110 wxConfigBase *cfg = wxConfig::Get();
111 wxString path = cfg->GetPath();
112 cfg->SetPath(m_context);
113 cfg->Write(_T("AlarmView/SortMode"), m_sortMode);
114 cfg->Write(_T("AlarmView/SortDir"), m_sortDir);
115 cfg->Write(_T("AlarmView/FontSize"), m_wndListCtrl->GetFont().GetPointSize());
116 NXMCSaveListCtrlColumns(cfg, *m_wndListCtrl, _T("AlarmView"));
117 cfg->SetPath(path);
118 }
119
120
121 //
122 // Resize handler
123 //
124
125 void nxAlarmView::OnSize(wxSizeEvent &event)
126 {
127 wxSize size = GetClientSize();
128 m_wndListCtrl->SetSize(0, 0, size.x, size.y);
129 }
130
131
132 //
133 // Refresh view
134 //
135
136 void nxAlarmView::RefreshView()
137 {
138 nxAlarmList *list;
139 nxAlarmList::iterator it;
140
141 m_wndListCtrl->DeleteAllItems();
142 list = NXMCGetAlarmList();
143
144 for(it = list->begin(); it != list->end(); it++)
145 {
146 if (MatchAlarm(it->second))
147 AddAlarm(it->second);
148 }
149
150 NXMCUnlockAlarmList();
151
152 SortAlarmList();
153 }
154
155
156 //
157 // Check if alarm matched to current filter settings
158 //
159
160 bool nxAlarmView::MatchAlarm(NXC_ALARM *alarm)
161 {
162 if (m_object == NULL)
163 return true;
164 if (m_object->dwId == alarm->dwSourceObject)
165 return true;
166 return NXCIsParent(NXMCGetSession(), m_object->dwId, alarm->dwSourceObject) ? true : false;
167 }
168
169
170 //
171 // Add alarm to view
172 //
173
174 void nxAlarmView::AddAlarm(NXC_ALARM *alarm)
175 {
176 long item;
177
178 item = m_wndListCtrl->InsertItem(0x7FFFFFFF, NXMCGetStatusTextSmall(alarm->nCurrentSeverity), alarm->nCurrentSeverity);
179 if (item != -1)
180 {
181 m_wndListCtrl->SetItemData(item, alarm->dwAlarmId);
182 UpdateAlarm(item, alarm);
183 }
184 }
185
186
187 //
188 // Update alarm in view
189 //
190
191 void nxAlarmView::UpdateAlarm(long item, NXC_ALARM *alarm)
192 {
193 NXC_OBJECT *object;
194 TCHAR temp[64];
195
196 m_wndListCtrl->SetItem(item, 0, NXMCGetStatusTextSmall(alarm->nCurrentSeverity), alarm->nCurrentSeverity);
197 m_wndListCtrl->SetItem(item, 1, NXMCGetAlarmStateName(alarm->nState), alarm->nState + STATUS_TESTING + 1);
198
199 object = NXCFindObjectById(NXMCGetSession(), alarm->dwSourceObject);
200 if (object != NULL)
201 {
202 m_wndListCtrl->SetItem(item, 2, object->szName);
203 }
204 else
205 {
206 m_wndListCtrl->SetItem(item, 2, _T("<unknown>"));
207 }
208
209 m_wndListCtrl->SetItem(item, 3, alarm->szMessage);
210
211 _sntprintf(temp, 64, _T("%d"), alarm->dwRepeatCount);
212 m_wndListCtrl->SetItem(item, 4, temp);
213
214 m_wndListCtrl->SetItem(item, 5, NXMCFormatTimeStamp(alarm->dwCreationTime, temp, TS_LONG_DATE_TIME));
215 m_wndListCtrl->SetItem(item, 6, NXMCFormatTimeStamp(alarm->dwLastChangeTime, temp, TS_LONG_DATE_TIME));
216 }
217
218
219 //
220 // Handler for right click on item
221 //
222
223 void nxAlarmView::OnListItemRightClick(wxListEvent &event)
224 {
225 wxMenu *menu;
226
227 if (!IsBusy())
228 {
229 menu = wxXmlResource::Get()->LoadMenu(_T("menuCtxAlarm"));
230 if (menu != NULL)
231 {
232 PopupMenu(menu);
233 delete menu;
234 }
235 }
236 }
237
238
239 //
240 // Alarm comparision callback
241 //
242
243 static nxAlarmList *s_alarmList;
244
245 static int wxCALLBACK CompareAlarms(long item1, long item2, long sortData)
246 {
247 long mode = sortData & 0x7FFF;
248 int rc;
249 nxAlarmList::iterator it1, it2;
250 NXC_OBJECT *obj1, *obj2;
251
252 it1 = s_alarmList->find(item1);
253 it2 = s_alarmList->find(item2);
254 if ((it1 == s_alarmList->end()) || (it2 == s_alarmList->end()))
255 {
256 wxLogDebug(_T("CompareAlarms: invalid iterator returned"));
257 return 0; // Shouldn't happen
258 }
259
260 switch(mode)
261 {
262 case 0: // Severity
263 rc = COMPARE_NUMBERS(it1->second->nCurrentSeverity, it2->second->nCurrentSeverity);
264 break;
265 case 1: // State
266 rc = COMPARE_NUMBERS(it1->second->nState, it2->second->nState);
267 break;
268 case 2: // Source
269 obj1 = NXCFindObjectById(NXMCGetSession(), it1->second->dwSourceObject);
270 obj2 = NXCFindObjectById(NXMCGetSession(), it2->second->dwSourceObject);
271 rc = _tcsicmp((obj1 != NULL) ? obj1->szName : _T("(null)"), (obj2 != NULL) ? obj2->szName : _T("(null)"));
272 break;
273 case 3: // Message
274 rc = _tcsicmp(it1->second->szMessage, it2->second->szMessage);
275 break;
276 case 4: // Count
277 rc = COMPARE_NUMBERS(it1->second->dwRepeatCount, it2->second->dwRepeatCount);
278 break;
279 case 5: // Created
280 rc = COMPARE_NUMBERS(it1->second->dwCreationTime, it2->second->dwCreationTime);
281 break;
282 case 6: // Last changed
283 rc = COMPARE_NUMBERS(it1->second->dwLastChangeTime, it2->second->dwLastChangeTime);
284 break;
285 default:
286 rc = 0;
287 break;
288 }
289
290 return (sortData & 0x8000) ? rc : -rc;
291 }
292
293
294 //
295 // Sort alarm list
296 //
297
298 void nxAlarmView::SortAlarmList()
299 {
300 s_alarmList = NXMCGetAlarmList();
301 m_wndListCtrl->SortItems(CompareAlarms, m_sortMode | ((m_sortDir == 1) ? 0x8000 : 0));
302 NXMCUnlockAlarmList();
303
304 // Mark sorting column
305 m_wndListCtrl->SetColumnImage(m_sortMode, STATUS_TESTING + ((m_sortDir == 1) ? 4 : 5));
306 }
307
308
309 //
310 // Handler for column click
311 //
312
313 void nxAlarmView::OnListColumnClick(wxListEvent &event)
314 {
315 m_wndListCtrl->ClearColumnImage(m_sortMode);
316
317 if (m_sortMode == event.GetColumn())
318 {
319 m_sortDir = -m_sortDir;
320 }
321 else
322 {
323 m_sortMode = event.GetColumn();
324 }
325 SortAlarmList();
326 }
327
328
329 //
330 // Handler for alarm change event
331 //
332
333 void nxAlarmView::OnAlarmChange(wxCommandEvent &event)
334 {
335 long item;
336 NXC_ALARM *alarm;
337
338 alarm = (NXC_ALARM *)event.GetClientData();
339 switch(event.GetInt())
340 {
341 case NX_NOTIFY_NEW_ALARM:
342 case NX_NOTIFY_ALARM_CHANGED:
343 item = m_wndListCtrl->FindItem(-1, alarm->dwAlarmId);
344 if (item != -1)
345 {
346 if (MatchAlarm(alarm))
347 UpdateAlarm(item, (NXC_ALARM *)event.GetClientData());
348 else
349 m_wndListCtrl->DeleteItem(item); // Alarm no longer match filter
350 }
351 else
352 {
353 if (MatchAlarm(alarm))
354 AddAlarm(alarm);
355 }
356 SortAlarmList();
357 break;
358 case NX_NOTIFY_ALARM_TERMINATED:
359 case NX_NOTIFY_ALARM_DELETED:
360 item = m_wndListCtrl->FindItem(-1, alarm->dwAlarmId);
361 if (item != -1)
362 m_wndListCtrl->DeleteItem(item);
363 break;
364 }
365 event.Skip();
366 }
367
368
369 //
370 // Handler for acknowledge alarm menu
371 //
372
373 static DWORD AckAlarms(int count, DWORD *list)
374 {
375 int i;
376 DWORD rcc;
377 NXC_SESSION session = NXMCGetSession();
378
379 for(i = 0; i < count; i++)
380 {
381 rcc = NXCAcknowledgeAlarm(session, list[i]);
382 if (rcc != RCC_SUCCESS)
383 break;
384 }
385 delete list;
386 return rcc;
387 }
388
389 void nxAlarmView::OnAlarmAck(wxCommandEvent &event)
390 {
391 int i, count = m_wndListCtrl->GetSelectedItemCount();
392 DWORD *idList = new DWORD[count];
393 long item;
394
395 for(i = 0, item = -1; i < count; i++)
396 {
397 item = m_wndListCtrl->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
398 if (item == -1)
399 break;
400 idList[i] = m_wndListCtrl->GetItemData(item);
401 }
402 if (count > 0)
403 DoRequestArg2((void *)AckAlarms, count, CAST_FROM_POINTER(idList, wxUIntPtr), _T("Cannot acknowledge alarm: %s"));
404 }
405
406 void nxAlarmView::OnUpdateAlarmAck(wxUpdateUIEvent &event)
407 {
408 event.Enable(m_wndListCtrl->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED) != -1);
409 }
410
411
412 //
413 // Handler for terminate alarm menu
414 //
415
416 static DWORD TerminateAlarms(int count, DWORD *list)
417 {
418 int i;
419 DWORD rcc;
420 NXC_SESSION session = NXMCGetSession();
421
422 for(i = 0; i < count; i++)
423 {
424 rcc = NXCTerminateAlarm(session, list[i]);
425 if (rcc != RCC_SUCCESS)
426 break;
427 }
428 delete list;
429 return rcc;
430 }
431
432 void nxAlarmView::OnAlarmTerminate(wxCommandEvent &event)
433 {
434 int i, count = m_wndListCtrl->GetSelectedItemCount();
435 DWORD *idList = new DWORD[count];
436 long item;
437
438 for(i = 0, item = -1; i < count; i++)
439 {
440 item = m_wndListCtrl->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
441 if (item == -1)
442 break;
443 idList[i] = m_wndListCtrl->GetItemData(item);
444 }
445 if (count > 0)
446 DoRequestArg2((void *)TerminateAlarms, count, CAST_FROM_POINTER(idList, wxUIntPtr), _T("Cannot terminate alarm: %s"));
447 }
448
449 void nxAlarmView::OnUpdateAlarmTerminate(wxUpdateUIEvent &event)
450 {
451 event.Enable(m_wndListCtrl->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED) != -1);
452 }
453
454
455 //
456 // Handler for delete alarm menu
457 //
458
459 static DWORD DeleteAlarms(int count, DWORD *list)
460 {
461 int i;
462 DWORD rcc;
463 NXC_SESSION session = NXMCGetSession();
464
465 for(i = 0; i < count; i++)
466 {
467 rcc = NXCDeleteAlarm(session, list[i]);
468 if (rcc != RCC_SUCCESS)
469 break;
470 }
471 delete list;
472 return rcc;
473 }
474
475 void nxAlarmView::OnAlarmDelete(wxCommandEvent &event)
476 {
477 int i, count = m_wndListCtrl->GetSelectedItemCount();
478 DWORD *idList = new DWORD[count];
479 long item;
480
481 for(i = 0, item = -1; i < count; i++)
482 {
483 item = m_wndListCtrl->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
484 if (item == -1)
485 break;
486 idList[i] = m_wndListCtrl->GetItemData(item);
487 }
488 if (count > 0)
489 DoRequestArg2((void *)DeleteAlarms, count, CAST_FROM_POINTER(idList, wxUIntPtr), _T("Cannot delete alarm: %s"));
490 }
491
492 void nxAlarmView::OnUpdateAlarmDelete(wxUpdateUIEvent &event)
493 {
494 event.Enable(m_wndListCtrl->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED) != -1);
495 }
496
497
498 //
499 // Increase font
500 //
501
502 void nxAlarmView::OnAlarmIncreaseFont(wxCommandEvent &event)
503 {
504 wxFont font;
505
506 font = m_wndListCtrl->GetFont();
507 if (font.GetPointSize() < 100)
508 {
509 font.SetPointSize(font.GetPointSize() + 1);
510 m_wndListCtrl->SetFont(font);
511 }
512 }
513
514
515 //
516 // Decrease font
517 //
518
519 void nxAlarmView::OnAlarmDecreaseFont(wxCommandEvent &event)
520 {
521 wxFont font;
522
523 font = m_wndListCtrl->GetFont();
524 if (font.GetPointSize() > 4)
525 {
526 font.SetPointSize(font.GetPointSize() - 1);
527 m_wndListCtrl->SetFont(font);
528 }
529 }
530
531
532 //
533 // Context menu handler
534 //
535
536 void nxAlarmView::OnContextMenu(wxContextMenuEvent &event)
537 {
538 wxMenu *menu;
539
540 if (!IsBusy())
541 {
542 menu = wxXmlResource::Get()->LoadMenu(_T("menuCtxAlarm"));
543 if (menu != NULL)
544 {
545 PopupMenu(menu);
546 delete menu;
547 }
548 }
549 }