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