- Implemented sorting in event editor
authorVictor Kirhenshtein <victor@netxms.org>
Thu, 6 Jul 2006 12:14:30 +0000 (12:14 +0000)
committerVictor Kirhenshtein <victor@netxms.org>
Thu, 6 Jul 2006 12:14:30 +0000 (12:14 +0000)
- Event editor and alarm browser now remembers width of columns

ChangeLog
src/console/win32/AlarmBrowser.cpp
src/console/win32/EventEditor.cpp
src/console/win32/EventEditor.h
src/console/win32/ObjectBrowser.cpp
src/console/win32/globals.cpp
src/console/win32/globals.h
src/console/win32/tools.cpp
src/server/tools/nxdbmgr/upgrade.cpp

index f39489c..538f640 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,10 +2,12 @@
 * 0.2.12
 *
 
+- Added possibility to define complicated conditions using "condition" objects
 - Implemented RADIUS authentication for NetXMS users
 - Added support for compressed MIB files
 - New MIBs added: ENTITY-MIB
 - Added support for DRBD device monitoring
+- Windows console: Event editor improved
 - Fixed issues: ???
 
 
index cc3b31b..2661fbd 100644 (file)
@@ -202,6 +202,7 @@ int CAlarmBrowser::OnCreate(LPCREATESTRUCT lpCreateStruct)
    m_wndListCtrl.InsertColumn(2, _T("Message"), LVCFMT_LEFT, 400);
    m_wndListCtrl.InsertColumn(3, _T("Time Stamp"), LVCFMT_LEFT, 135);
    m_wndListCtrl.InsertColumn(4, _T("Ack"), LVCFMT_CENTER, 30);
+   LoadListCtrlColumns(m_wndListCtrl, _T("AlarmBrowser"), _T("ListCtrl"));
        
    // Mark sorting column in list control
    lvCol.mask = LVCF_IMAGE | LVCF_FMT;
@@ -255,6 +256,7 @@ int CAlarmBrowser::OnCreate(LPCREATESTRUCT lpCreateStruct)
 
 void CAlarmBrowser::OnDestroy() 
 {
+   SaveListCtrlColumns(m_wndListCtrl, _T("AlarmBrowser"), _T("ListCtrl"));
    DoRequestArg2(NXCUnsubscribe, g_hSession, (void *)NXC_CHANNEL_ALARMS,
                  _T("Unsubscribing from ALARMS channel..."));
    theApp.OnViewDestroy(VIEW_ALARMS, this);
index 361b6b7..9403acf 100644 (file)
@@ -20,11 +20,15 @@ IMPLEMENT_DYNCREATE(CEventEditor, CMDIChildWnd)
 CEventEditor::CEventEditor()
 {
    m_pImageList = NULL;
+   m_iSortMode = theApp.GetProfileInt(_T("EventEditor"), _T("SortMode"), 0);
+   m_iSortDir = theApp.GetProfileInt(_T("EventEditor"), _T("SortDir"), 0);
 }
 
 CEventEditor::~CEventEditor()
 {
    delete m_pImageList;
+   theApp.WriteProfileInt(_T("EventEditor"), _T("SortMode"), m_iSortMode);
+   theApp.WriteProfileInt(_T("EventEditor"), _T("SortDir"), m_iSortDir);
 }
 
 
@@ -44,8 +48,20 @@ BEGIN_MESSAGE_MAP(CEventEditor, CMDIChildWnd)
        ON_COMMAND(ID_UPDATE_EVENT_LIST, OnUpdateEventList)
        //}}AFX_MSG_MAP
    ON_NOTIFY(NM_DBLCLK, IDC_LIST_VIEW, OnListViewDoubleClick)
+       ON_NOTIFY(LVN_COLUMNCLICK, IDC_LIST_VIEW, OnListViewColumnClick)
 END_MESSAGE_MAP()
 
+
+//
+// Item compare callback
+//
+
+static int CALLBACK CompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
+{
+   return ((CEventEditor *)lParamSort)->CompareListItems(lParam1, lParam2);
+}
+
+
 //
 // CEventEditor message handlers
 //
@@ -54,6 +70,7 @@ int CEventEditor::OnCreate(LPCREATESTRUCT lpCreateStruct)
 {
    RECT rect;
    TCHAR szBuffer[32];
+   LVCOLUMN lvCol;
    DWORD i;
 
        if (CMDIChildWnd::OnCreate(lpCreateStruct) == -1)
@@ -63,21 +80,24 @@ int CEventEditor::OnCreate(LPCREATESTRUCT lpCreateStruct)
 
    // Create list view control
    GetClientRect(&rect);
-   m_wndListCtrl.Create(WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SHOWSELALWAYS, rect, this, IDC_LIST_VIEW);
-   m_wndListCtrl.SetExtendedStyle(LVS_EX_TRACKSELECT | LVS_EX_UNDERLINEHOT | 
-                                  LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
+   m_wndListCtrl.Create(WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS, rect, this, IDC_LIST_VIEW);
+   m_wndListCtrl.SetExtendedStyle(LVS_EX_LABELTIP | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
    m_wndListCtrl.SetHoverTime(0x7FFFFFFF);
 
    // Setup columns
    m_wndListCtrl.InsertColumn(0, _T("ID"), LVCFMT_LEFT, 60);
    m_wndListCtrl.InsertColumn(1, _T("Name"), LVCFMT_LEFT, 190);
    m_wndListCtrl.InsertColumn(2, _T("Severity"), LVCFMT_LEFT, 70);
-   m_wndListCtrl.InsertColumn(3, _T("Flags"), LVCFMT_LEFT, 40);
+   m_wndListCtrl.InsertColumn(3, _T("Log"), LVCFMT_LEFT, 40);
    m_wndListCtrl.InsertColumn(4, _T("Message"), LVCFMT_LEFT, 300);
    m_wndListCtrl.InsertColumn(5, _T("Description"), LVCFMT_LEFT, 300);
+   LoadListCtrlColumns(m_wndListCtrl, _T("EventEditor"), _T("ListCtrl"));
        
    // Create image list
    m_pImageList = CreateEventImageList();
+   m_iSortImageBase = m_pImageList->GetImageCount();
+   m_pImageList->Add(theApp.LoadIcon(IDI_SORT_UP));
+   m_pImageList->Add(theApp.LoadIcon(IDI_SORT_DOWN));
    m_wndListCtrl.SetImageList(m_pImageList, LVSIL_SMALL);
 
    // Load event templates
@@ -90,6 +110,14 @@ int CEventEditor::OnCreate(LPCREATESTRUCT lpCreateStruct)
       UpdateItem(i, m_ppEventTemplates[i]);
    }
 
+   // Mark sorting column
+   lvCol.mask = LVCF_IMAGE | LVCF_FMT;
+   lvCol.fmt = LVCFMT_BITMAP_ON_RIGHT | LVCFMT_IMAGE | LVCFMT_LEFT;
+   lvCol.iImage = m_iSortImageBase + m_iSortDir;
+   m_wndListCtrl.SetColumn(m_iSortMode, &lvCol);
+
+   m_wndListCtrl.SortItems(CompareItems, (UINT_PTR)this);
+
    return 0;
 }
 
@@ -100,13 +128,10 @@ int CEventEditor::OnCreate(LPCREATESTRUCT lpCreateStruct)
 
 void CEventEditor::UpdateItem(int iItem, NXC_EVENT_TEMPLATE *pData)
 {
-   TCHAR szBuffer[32];
-
    m_wndListCtrl.SetItem(iItem, 0, LVIF_IMAGE, NULL, pData->dwSeverity, 0, 0, 0);
    m_wndListCtrl.SetItemText(iItem, 1, pData->szName);
    m_wndListCtrl.SetItemText(iItem, 2, g_szStatusTextSmall[pData->dwSeverity]);
-   _stprintf(szBuffer, _T("%d"), pData->dwFlags);
-   m_wndListCtrl.SetItemText(iItem, 3, szBuffer);
+   m_wndListCtrl.SetItemText(iItem, 3, (pData->dwFlags & EF_LOG) ? _T("Yes") : _T("No"));
    m_wndListCtrl.SetItemText(iItem, 4, pData->pszMessage);
    m_wndListCtrl.SetItemText(iItem, 5, pData->pszDescription);
 }
@@ -118,6 +143,7 @@ void CEventEditor::UpdateItem(int iItem, NXC_EVENT_TEMPLATE *pData)
 
 void CEventEditor::OnDestroy() 
 {
+   SaveListCtrlColumns(m_wndListCtrl, _T("EventEditor"), _T("ListCtrl"));
    theApp.OnViewDestroy(VIEW_EVENT_EDITOR, this);
        CMDIChildWnd::OnDestroy();
 }
@@ -409,3 +435,89 @@ void CEventEditor::OnUpdateEventList()
 {
    NXCGetEventDB(g_hSession, &m_ppEventTemplates, &m_dwNumTemplates);
 }
+
+
+//
+// Compare two list items
+//
+
+int CEventEditor::CompareListItems(DWORD dwId1, DWORD dwId2)
+{
+   int nStatus1, nStatus2, nRet, nItem1, nItem2;
+   TCHAR szText1[4096], szText2[4096];
+   LVFINDINFO lvfi;
+
+   if (m_iSortMode != 0)
+   {
+      lvfi.flags = LVFI_PARAM;
+      lvfi.lParam = dwId1;
+      nItem1 = m_wndListCtrl.FindItem(&lvfi, -1);
+      lvfi.lParam = dwId2;
+      nItem2 = m_wndListCtrl.FindItem(&lvfi, -1);
+   }
+   switch(m_iSortMode)
+   {
+      case 0:  // ID
+         nRet = COMPARE_NUMBERS(dwId1, dwId2);
+         break;
+      case 2:  // Severity
+         m_wndListCtrl.GetItemText(nItem1, m_iSortMode, szText1, 4096);
+         m_wndListCtrl.GetItemText(nItem2, m_iSortMode, szText2, 4096);
+         for(nStatus1 = 0; g_szStatusTextSmall[nStatus1] != NULL; nStatus1++)
+            if (!_tcsicmp(g_szStatusTextSmall[nStatus1], szText1))
+               break;
+         for(nStatus2 = 0; g_szStatusTextSmall[nStatus2] != NULL; nStatus2++)
+            if (!_tcsicmp(g_szStatusTextSmall[nStatus2], szText2))
+               break;
+         nRet = COMPARE_NUMBERS(nStatus1, nStatus2);
+         break;
+      case 1:  // Name
+      case 3:  // Log
+      case 4:  // Message
+      case 5:  // Description
+         m_wndListCtrl.GetItemText(nItem1, m_iSortMode, szText1, 4096);
+         m_wndListCtrl.GetItemText(nItem2, m_iSortMode, szText2, 4096);
+         nRet = _tcsicmp(szText1, szText2);
+         break;
+      default:
+         nRet = 0;
+         break;
+   }
+   return (m_iSortDir == 0) ? nRet : -nRet;
+}
+
+
+//
+// WM_NOTIFY::LVN_COLUMNCLICK message handler
+//
+
+void CEventEditor::OnListViewColumnClick(LPNMLISTVIEW pNMHDR, LRESULT *pResult)
+{
+   LVCOLUMN lvCol;
+
+   // Unmark old sorting column
+   lvCol.mask = LVCF_FMT;
+   lvCol.fmt = LVCFMT_LEFT;
+   m_wndListCtrl.SetColumn(m_iSortMode, &lvCol);
+
+   // Change current sort mode and resort list
+   if (m_iSortMode == pNMHDR->iSubItem)
+   {
+      // Same column, change sort direction
+      m_iSortDir = !m_iSortDir;
+   }
+   else
+   {
+      // Another sorting column
+      m_iSortMode = pNMHDR->iSubItem;
+   }
+   m_wndListCtrl.SortItems(CompareItems, (UINT_PTR)this);
+
+   // Mark new sorting column
+   lvCol.mask = LVCF_IMAGE | LVCF_FMT;
+   lvCol.fmt = LVCFMT_BITMAP_ON_RIGHT | LVCFMT_IMAGE | LVCFMT_LEFT;
+   lvCol.iImage = m_iSortImageBase + m_iSortDir;
+   m_wndListCtrl.SetColumn(m_iSortMode, &lvCol);
+   
+   *pResult = 0;
+}
index df72d5b..30549b7 100644 (file)
@@ -21,6 +21,7 @@ public:
 
 // Operations
 public:
+       int CompareListItems(DWORD dwId1, DWORD dwId2);
    DWORD DeleteEvents(DWORD dwNumEvents, DWORD *pdwEventList);
 
 // Overrides
@@ -32,10 +33,12 @@ public:
 
 // Implementation
 protected:
+       int m_iSortMode;
+       int m_iSortDir;
+       int m_iSortImageBase;
        void UpdateItem(int iItem, NXC_EVENT_TEMPLATE *pData);
        CImageList *m_pImageList;
        BOOL EditEvent(int iItem);
-       afx_msg void OnListViewDoubleClick(NMITEMACTIVATE *pInfo, LRESULT *pResult);
        DWORD m_dwNumTemplates;
        NXC_EVENT_TEMPLATE ** m_ppEventTemplates;
        CListCtrl m_wndListCtrl;
@@ -56,6 +59,8 @@ protected:
        afx_msg void OnEventDelete();
        afx_msg void OnUpdateEventList();
        //}}AFX_MSG
+       afx_msg void OnListViewDoubleClick(NMITEMACTIVATE *pInfo, LRESULT *pResult);
+   afx_msg void OnListViewColumnClick(LPNMLISTVIEW pNMHDR, LRESULT *pResult);
        DECLARE_MESSAGE_MAP()
 };
 
index e7c45c4..e4fb086 100644 (file)
@@ -281,7 +281,7 @@ int CObjectBrowser::OnCreate(LPCREATESTRUCT lpCreateStruct)
    // Create list view control
    m_wndListCtrl.Create(WS_CHILD | LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS, rect, this, IDC_LIST_VIEW);
    m_wndListCtrl.SetExtendedStyle(LVS_EX_TRACKSELECT | LVS_EX_UNDERLINEHOT | 
-                                  LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
+                                  LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_LABELTIP);
    m_wndListCtrl.SetHoverTime(0x7FFFFFFF);
 
    // Setup list view columns
index bfa2099..81073e9 100644 (file)
@@ -88,10 +88,10 @@ CImageList *g_pObjectNormalImageList = NULL;
 
 TCHAR *g_szStatusText[] = { _T("NORMAL"), _T("WARNING"), _T("MINOR"), _T("MAJOR"),
                             _T("CRITICAL"), _T("UNKNOWN"), _T("UNMANAGED"),
-                            _T("DISABLED"), _T("TESTING") };
+                            _T("DISABLED"), _T("TESTING"), NULL };
 TCHAR *g_szStatusTextSmall[] = { _T("Normal"), _T("Warning"), _T("Minor"), _T("Major"),
                                  _T("Critical"), _T("Unknown"), _T("Unmanaged"),
-                                 _T("Disabled"), _T("Testing") };
+                                 _T("Disabled"), _T("Testing"), NULL };
 TCHAR *g_szObjectClass[] = { _T("Generic"), _T("Subnet"), _T("Node"), _T("Interface"), _T("Network"), 
                              _T("Container"), _T("Zone"), _T("ServiceRoot"), _T("Template"), 
                              _T("TemplateGroup"), _T("TemplateRoot"), _T("NetworkService"),
index 8492f64..af7dd5c 100644 (file)
@@ -311,6 +311,8 @@ TCHAR **CopyStringList(TCHAR **ppList, DWORD dwSize);
 void DestroyStringList(TCHAR **ppList, DWORD dwSize);
 HTREEITEM FindTreeCtrlItem(CTreeCtrl &ctrl, HTREEITEM hRoot, TCHAR *pszText);
 HTREEITEM FindTreeCtrlItemEx(CTreeCtrl &ctrl, HTREEITEM hRoot, DWORD dwData);
+void SaveListCtrlColumns(CListCtrl &wndListCtrl, TCHAR *pszSection, TCHAR *pszPrefix);
+void LoadListCtrlColumns(CListCtrl &wndListCtrl, TCHAR *pszSection, TCHAR *pszPrefix);
 
 
 //
index cebd4b7..d5d83f6 100644 (file)
@@ -800,3 +800,48 @@ HBITMAP LoadPicture(TCHAR *pszFile, int nScaleFactor)
 
        return hBitmap;
 }
+
+
+//
+// Save dimensions of all list control columns into registry
+//
+
+void SaveListCtrlColumns(CListCtrl &wndListCtrl, TCHAR *pszSection, TCHAR *pszPrefix)
+{
+   int i;
+   LVCOLUMN lvc;
+   TCHAR szParam[256];
+
+   lvc.mask = LVCF_WIDTH;
+   for(i = 0; wndListCtrl.GetColumn(i, &lvc); i++)
+   {
+      _sntprintf(szParam, 256, _T("%s_%d"), pszPrefix, i);
+      theApp.WriteProfileInt(pszSection, szParam, lvc.cx);
+   }
+
+   _sntprintf(szParam, 256, _T("%s_CNT"), pszPrefix);
+   theApp.WriteProfileInt(pszSection, szParam, i);
+}
+
+
+//
+// Load and set dimensions of all list control columns
+//
+
+void LoadListCtrlColumns(CListCtrl &wndListCtrl, TCHAR *pszSection, TCHAR *pszPrefix)
+{
+   int i, nCount;
+   LVCOLUMN lvc;
+   TCHAR szParam[256];
+
+   _sntprintf(szParam, 256, _T("%s_CNT"), pszPrefix);
+   nCount = theApp.GetProfileInt(pszSection, szParam, 0);
+
+   lvc.mask = LVCF_WIDTH;
+   for(i = 0; i < nCount; i++)
+   {
+      _sntprintf(szParam, 256, _T("%s_%d"), pszPrefix, i);
+      lvc.cx = theApp.GetProfileInt(pszSection, szParam, 50);
+      wndListCtrl.SetColumn(i, &lvc);
+   }
+}
index 2c57a6a..64fd2f2 100644 (file)
@@ -77,6 +77,73 @@ static BOOL CreateConfigParam(TCHAR *pszName, TCHAR *pszValue, int iVisible, int
 }
 
 
+//
+// Upgrade from V41 to V42
+//
+
+static BOOL H_UpgradeFromV41(void)
+{
+   static TCHAR m_szBatch[] =
+          "INSERT INTO images (image_id,name,file_name_png,file_hash_png,"
+         "file_name_ico,file_hash_ico) VALUES (15,'Obj.Condition',"
+         "'condition.png','<invalid_hash>','condition.ico','<invalid_hash>')\n"
+          "INSERT INTO default_images (object_class,image_id) VALUES (13, 15)\n"
+          "INSERT INTO oid_to_type (pair_id,snmp_oid,node_type,node_flags) "
+             "VALUES (1,'.1.3.6.1.4.1.3224.1.*',2,0)\n"
+          "INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description) "
+         "VALUES (34,'SYS_CONDITION_ACTIVATED',2,1,'Condition \"%2\" activated',"
+                       "'Default event for condition activation.#0D#0AParameters:#0D#0A"
+                       "   1) Condition object ID#0D#0A   2) Condition object name#0D#0A"
+                       "   3) Previous condition status#0D#0A   4) Current condition status')\n"
+          "INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description) "
+         "VALUES (35,'SYS_CONDITION_DEACTIVATED',0,1,'Condition \"%2\" deactivated',"
+                       "'Default event for condition deactivation.#0D#0AParameters:#0D#0A"
+                       "   1) Condition object ID#0D#0A   2) Condition object name#0D#0A"
+                       "   3) Previous condition status#0D#0A   4) Current condition status')\n"
+      "<END>";
+
+   if (!CreateTable(_T("CREATE TABLE conditions        ("
+                                "id integer not null,"
+                                "activation_event integer not null,"
+                                "deactivation_event integer not null,"
+                                "source_object integer not null,"
+                                "active_status integer not null,"
+                                "inactive_status integer not null,"
+                                "script $SQL:TEXT not null,"
+                                "PRIMARY KEY(id))")))
+      if (!g_bIgnoreErrors)
+         return FALSE;
+
+   if (!CreateTable(_T("CREATE TABLE cond_dci_map ("
+                                "condition_id integer not null,"
+                                "dci_id integer not null,"
+                                "node_id integer not null,"
+                                "dci_func integer not null,"
+                                "num_polls integer not null,"
+                                "PRIMARY KEY(condition_id,dci_id))")))
+      if (!g_bIgnoreErrors)
+         return FALSE;
+
+   if (!SQLBatch(m_szBatch))
+      if (!g_bIgnoreErrors)
+         return FALSE;
+
+   if (!CreateConfigParam(_T("NumberOfConditionPollers"), _T("10"), 1, 1))
+      if (!g_bIgnoreErrors)
+         return FALSE;
+
+   if (!CreateConfigParam(_T("ConditionPollingInterval"), _T("60"), 1, 1))
+      if (!g_bIgnoreErrors)
+         return FALSE;
+
+   if (!SQLQuery(_T("UPDATE config SET var_value='42' WHERE var_name='DBFormatVersion'")))
+      if (!g_bIgnoreErrors)
+         return FALSE;
+
+   return TRUE;
+}
+
+
 //
 // Upgrade from V40 to V41
 //
@@ -1823,6 +1890,7 @@ static struct
    { 38, H_UpgradeFromV38 },
    { 39, H_UpgradeFromV39 },
    { 40, H_UpgradeFromV40 },
+   { 41, H_UpgradeFromV41 },
    { 0, NULL }
 };