Implemented event group functionality. Fixes #NX-1102
authorEriks Jenkevics <eriks@netxms.org>
Wed, 16 Aug 2017 14:19:41 +0000 (17:19 +0300)
committerEriks Jenkevics <eriks@netxms.org>
Thu, 14 Sep 2017 05:21:03 +0000 (08:21 +0300)
83 files changed:
ChangeLog
include/netxmsdb.h
include/nxconfig.h
sql/schema.in
sql/setup.in
src/java/client/netxms-client/src/main/java/org/netxms/client/NXCSession.java
src/java/client/netxms-client/src/main/java/org/netxms/client/events/EventGroup.java [new file with mode: 0644]
src/java/client/netxms-client/src/main/java/org/netxms/client/events/EventObject.java [new file with mode: 0644]
src/java/client/netxms-client/src/main/java/org/netxms/client/events/EventTemplate.java
src/java/client/netxms-client/src/test/java/org/netxms/client/ConnectionTest.java
src/java/client/netxms-client/src/test/java/org/netxms/client/EventDatabaseSyncTest.java
src/java/netxms-eclipse/Core/icons/container.png [new file with mode: 0644]
src/java/netxms-eclipse/Core/src/org/netxms/ui/eclipse/console/resources/SharedIcons.java
src/java/netxms-eclipse/Core/src/org/netxms/ui/eclipse/jobs/LoginJob.java
src/java/netxms-eclipse/DataCollection/src/org/netxms/ui/eclipse/datacollection/ThresholdLabelProvider.java
src/java/netxms-eclipse/DataCollection/src/org/netxms/ui/eclipse/datacollection/propertypages/helpers/TableThresholdLabelProvider.java
src/java/netxms-eclipse/EPP/src/org/netxms/ui/eclipse/epp/propertypages/RuleEvents.java
src/java/netxms-eclipse/EPP/src/org/netxms/ui/eclipse/epp/propertypages/helpers/EventObjectLabelProvider.java [moved from src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/views/helpers/EventTemplateLabelProvider.java with 55% similarity]
src/java/netxms-eclipse/EPP/src/org/netxms/ui/eclipse/epp/views/EventProcessingPolicyEditor.java
src/java/netxms-eclipse/EPP/src/org/netxms/ui/eclipse/epp/widgets/RuleEditor.java
src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/dialogs/EditEventGroupDialog.java [new file with mode: 0644]
src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/dialogs/EventSelectionDialog.java
src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/dialogs/helpers/EventListFilter.java
src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/dialogs/helpers/EventObjectComparator.java [moved from src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/views/helpers/EventTemplateComparator.java with 58% similarity]
src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/views/EventConfigurator.java
src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/views/helpers/EventObjectComparator.java [new file with mode: 0644]
src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/views/helpers/EventObjectContentProvider.java [new file with mode: 0644]
src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/views/helpers/EventObjectFilter.java [new file with mode: 0644]
src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/views/helpers/EventObjectLabelProvider.java [new file with mode: 0644]
src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/views/helpers/EventTemplateFilter.java [deleted file]
src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/widgets/EventObjectList.java [new file with mode: 0644]
src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/widgets/EventSelector.java
src/java/netxms-eclipse/LogViewer/src/org/netxms/ui/eclipse/logviewer/views/helpers/LogLabelProvider.java
src/java/netxms-eclipse/LogViewer/src/org/netxms/ui/eclipse/logviewer/widgets/EventConditionEditor.java
src/java/netxms-eclipse/Reporter/src/org/netxms/ui/eclipse/reporter/widgets/EventFieldEditor.java
src/java/netxms-eclipse/SNMP/src/org/netxms/ui/eclipse/snmp/views/helpers/SnmpTrapComparator.java
src/java/netxms-eclipse/SNMP/src/org/netxms/ui/eclipse/snmp/views/helpers/SnmpTrapLabelProvider.java
src/java/netxms-eclipse/ServerConfig/src/org/netxms/ui/eclipse/serverconfig/dialogs/helpers/SnmpTrapComparator.java
src/java/netxms-eclipse/ServerConfig/src/org/netxms/ui/eclipse/serverconfig/dialogs/helpers/SnmpTrapFilter.java
src/java/netxms-eclipse/ServerConfig/src/org/netxms/ui/eclipse/serverconfig/dialogs/helpers/TrapListLabelProvider.java
src/java/netxms-eclipse/ServerConfig/src/org/netxms/ui/eclipse/serverconfig/views/ExportFileBuilder.java
src/java/netxms-eclipse/ServerConfig/src/org/netxms/ui/eclipse/serverconfig/widgets/helpers/LogParserRuleEditor.java
src/libnetxms/config.cpp
src/server/core/dcitem.cpp
src/server/core/ef.cpp
src/server/core/epp.cpp
src/server/core/events.cpp
src/server/core/import.cpp
src/server/core/session.cpp
src/server/core/syslogd.cpp
src/server/include/nms_core.h
src/server/include/nms_events.h
src/server/tools/nxdbmgr/upgrade.cpp
webui/webapp/Core/src/org/netxms/ui/eclipse/console/resources/SharedIcons.java
webui/webapp/Core/src/org/netxms/ui/eclipse/jobs/LoginJob.java
webui/webapp/DataCollection/src/org/netxms/ui/eclipse/datacollection/ThresholdLabelProvider.java
webui/webapp/DataCollection/src/org/netxms/ui/eclipse/datacollection/propertypages/helpers/TableThresholdLabelProvider.java
webui/webapp/EPP/src/org/netxms/ui/eclipse/epp/propertypages/RuleEvents.java
webui/webapp/EPP/src/org/netxms/ui/eclipse/epp/propertypages/helpers/EventObjectLabelProvider.java [moved from webui/webapp/EventManager/src/org/netxms/ui/eclipse/eventmanager/views/helpers/EventTemplateLabelProvider.java with 54% similarity]
webui/webapp/EPP/src/org/netxms/ui/eclipse/epp/views/EventProcessingPolicyEditor.java
webui/webapp/EPP/src/org/netxms/ui/eclipse/epp/widgets/RuleEditor.java
webui/webapp/EventManager/src/org/netxms/ui/eclipse/eventmanager/dialogs/EditEventGroupDialog.java [new file with mode: 0644]
webui/webapp/EventManager/src/org/netxms/ui/eclipse/eventmanager/dialogs/EventSelectionDialog.java
webui/webapp/EventManager/src/org/netxms/ui/eclipse/eventmanager/dialogs/helpers/EventListFilter.java
webui/webapp/EventManager/src/org/netxms/ui/eclipse/eventmanager/dialogs/helpers/EventObjectComparator.java [moved from webui/webapp/EventManager/src/org/netxms/ui/eclipse/eventmanager/views/helpers/EventTemplateComparator.java with 58% similarity]
webui/webapp/EventManager/src/org/netxms/ui/eclipse/eventmanager/views/EventConfigurator.java
webui/webapp/EventManager/src/org/netxms/ui/eclipse/eventmanager/views/helpers/EventObjectComparator.java [new file with mode: 0644]
webui/webapp/EventManager/src/org/netxms/ui/eclipse/eventmanager/views/helpers/EventObjectContentProvider.java [new file with mode: 0644]
webui/webapp/EventManager/src/org/netxms/ui/eclipse/eventmanager/views/helpers/EventObjectFilter.java [new file with mode: 0644]
webui/webapp/EventManager/src/org/netxms/ui/eclipse/eventmanager/views/helpers/EventObjectLabelProvider.java [new file with mode: 0644]
webui/webapp/EventManager/src/org/netxms/ui/eclipse/eventmanager/views/helpers/EventTemplateFilter.java [deleted file]
webui/webapp/EventManager/src/org/netxms/ui/eclipse/eventmanager/widgets/EventObjectList.java [new file with mode: 0644]
webui/webapp/EventManager/src/org/netxms/ui/eclipse/eventmanager/widgets/EventSelector.java
webui/webapp/LogViewer/src/org/netxms/ui/eclipse/logviewer/views/helpers/LogLabelProvider.java
webui/webapp/LogViewer/src/org/netxms/ui/eclipse/logviewer/widgets/EventConditionEditor.java
webui/webapp/Reporter/src/org/netxms/ui/eclipse/reporter/widgets/EventFieldEditor.java
webui/webapp/SNMP/src/org/netxms/ui/eclipse/snmp/views/helpers/SnmpTrapComparator.java
webui/webapp/SNMP/src/org/netxms/ui/eclipse/snmp/views/helpers/SnmpTrapLabelProvider.java
webui/webapp/ServerConfig/src/org/netxms/ui/eclipse/serverconfig/dialogs/helpers/SnmpTrapComparator.java
webui/webapp/ServerConfig/src/org/netxms/ui/eclipse/serverconfig/dialogs/helpers/SnmpTrapFilter.java
webui/webapp/ServerConfig/src/org/netxms/ui/eclipse/serverconfig/dialogs/helpers/TrapListLabelProvider.java
webui/webapp/ServerConfig/src/org/netxms/ui/eclipse/serverconfig/views/ExportFileBuilder.java
webui/webapp/ServerConfig/src/org/netxms/ui/eclipse/serverconfig/widgets/helpers/LogParserRuleEditor.java

index 4624a4e..2275b5b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -11,7 +11,7 @@
 - Summary tables for table DCIs
 - Multi-valued columns in summary tables
 - Threshold violation events have current DCI value as parameter 8 (named as "dciValue")
-- Fixed issues: NX-1309, NX-1314
+- Fixed issues: NX-1102, NX-1309, NX-1314
 
 
 *
index a08eeff..5143090 100644 (file)
@@ -23,6 +23,6 @@
 #ifndef _netxmsdb_h
 #define _netxmsdb_h
 
-#define DB_FORMAT_VERSION   501
+#define DB_FORMAT_VERSION   502
 
 #endif
index b57f3a9..12ea678 100644 (file)
@@ -177,6 +177,8 @@ public:
 
    void setAlias(const TCHAR *alias, const TCHAR *value) { if (alias != NULL) m_aliases.set(alias, value); else m_aliases.remove(alias); }
    const TCHAR *getAlias(const TCHAR *alias) const { return m_aliases.get(alias); }
+
+   bool isExpansionAllowed() { return m_allowMacroExpansion; }
 };
 
 
index f59b002..95973a1 100644 (file)
@@ -840,11 +840,10 @@ CREATE TABLE actions
 */
 CREATE TABLE event_groups
 (
+  guid varchar(36) not null,
   id integer not null,
   name varchar(63) not null,
   description varchar(255) not null,
-  range_start integer not null,
-  range_end integer not null,
   PRIMARY KEY(id)
 ) TABLE_TYPE;
 
@@ -878,6 +877,7 @@ CREATE TABLE event_policy
 
 /**
  *
+ *
  */
 CREATE TABLE policy_source_list
 (
index 889564e..0fdf479 100644 (file)
@@ -298,10 +298,10 @@ INSERT INTO acl (object_id,user_id,access_rights) VALUES (9,-2147483647,65535);
 #define ID_GROUP_1 -2147483647
 #define ID_GROUP_2 -2147483646
 
-INSERT INTO event_groups (id,name,description,range_start,range_end)
-   VALUES (ID_GROUP_1,'NodeStatus','All events reporting about node status change',0,0);
-INSERT INTO event_groups (id,name,description,range_start,range_end)
-   VALUES (ID_GROUP_2,'NewObjects','All events reporting about new objects creation',0,0);
+INSERT INTO event_groups (guid,id,name,description)
+   VALUES (04b326c0-5cc0-411f-8587-2836cb87c920,ID_GROUP_1,'NodeStatus','All events reporting about node status change');
+INSERT INTO event_groups (guid,id,name,description)
+   VALUES (b61859c6-1768-4a61-a0cf-eed07d688f66,ID_GROUP_2,'NewObjects','All events reporting about new objects creation');
 
 INSERT INTO event_group_members (group_id,event_code) VALUES (ID_GROUP_1,EVENT_NODE_NORMAL);
 INSERT INTO event_group_members (group_id,event_code) VALUES (ID_GROUP_1,EVENT_NODE_MINOR);
index 80989cb..e555af4 100644 (file)
@@ -100,9 +100,9 @@ import org.netxms.client.events.AlarmComment;
 import org.netxms.client.events.BulkAlarmStateChangeData;
 import org.netxms.client.events.Event;
 import org.netxms.client.events.EventInfo;
+import org.netxms.client.events.EventObject;
 import org.netxms.client.events.EventProcessingPolicy;
 import org.netxms.client.events.EventProcessingPolicyRule;
-import org.netxms.client.events.EventTemplate;
 import org.netxms.client.events.SyslogRecord;
 import org.netxms.client.log.Log;
 import org.netxms.client.maps.MapDCIInstance;
@@ -322,9 +322,9 @@ public class NXCSession
    // Users
    private Map<Long, AbstractUserObject> userDB = new HashMap<Long, AbstractUserObject>();
 
-   // Event templates
-   private Map<Long, EventTemplate> eventTemplates = new HashMap<Long, EventTemplate>();
-   private boolean eventTemplatesNeedSync = false;
+   // Event objects
+   private Map<Long, EventObject> eventObjects = new HashMap<Long, EventObject>();
+   private boolean eventObjectsNeedSync = false;
    
    // Alarm categories
    private Map<Long, AlarmCategory> alarmCategories = new HashMap<Long, AlarmCategory>();
@@ -693,9 +693,9 @@ public class NXCSession
                strictAlarmStatusFlow = ((int)data != 0);
                break;
             case SessionNotification.RELOAD_EVENT_DB:
-               if (eventTemplatesNeedSync)
+               if (eventObjectsNeedSync)
                {
-                  resyncEventTemplates();
+                  resyncEventObjects();
                }
                break;
             case SessionNotification.SESSION_KILLED:
@@ -851,22 +851,22 @@ public class NXCSession
       {
          int code = msg.getFieldAsInt32(NXCPCodes.VID_NOTIFICATION_CODE) + SessionNotification.NOTIFY_BASE;
          long eventCode = msg.getFieldAsInt64(NXCPCodes.VID_EVENT_CODE);
-         EventTemplate et = (code != SessionNotification.EVENT_TEMPLATE_DELETED) ? new EventTemplate(msg) : null;
-         if (eventTemplatesNeedSync)
+         EventObject obj = (code != SessionNotification.EVENT_TEMPLATE_DELETED) ? EventObject.createFromMessage(msg, NXCPCodes.VID_ELEMENT_LIST_BASE) : null;
+         if (eventObjectsNeedSync)
          {
-            synchronized(eventTemplates)
+            synchronized(eventObjects)
             {
                if (code == SessionNotification.EVENT_TEMPLATE_DELETED)
                {
-                  eventTemplates.remove(eventCode);
+                  eventObjects.remove(eventCode);
                }
                else
                {
-                  eventTemplates.put(eventCode, et);
+                  eventObjects.put(obj.getCode(), obj);
                }
             }
          }
-         sendNotification(new SessionNotification(code, eventCode, et));
+         sendNotification(new SessionNotification(code, obj == null ? eventCode : obj.getCode(), obj));
       }
       
       /**
@@ -2118,7 +2118,7 @@ public class NXCSession
       objectList.clear();
       objectListGUID.clear();
       zoneList.clear();
-      eventTemplates.clear();
+      eventObjects.clear();
       userDB.clear();
       alarmCategories.clear();
    }
@@ -6148,24 +6148,24 @@ public class NXCSession
     * @throws IOException  if socket I/O error occurs
     * @throws NXCException if NetXMS server returns an error or operation was timed out
     */
-   public void syncEventTemplates() throws IOException, NXCException
+   public void syncEventObjects() throws IOException, NXCException
    {
-      List<EventTemplate> templates = getEventTemplates();
-      synchronized(eventTemplates)
+      List<EventObject> objects = getEventObjects();
+      synchronized(eventObjects)
       {
-         eventTemplates.clear();
-         for(EventTemplate t : templates)
+         eventObjects.clear();
+         for(EventObject o : objects)
          {
-            eventTemplates.put(t.getCode(), t);
+            eventObjects.put(o.getCode(), o);
          }
-         eventTemplatesNeedSync = true;
+         eventObjectsNeedSync = true;
       }
    }
    
    /**
     * Re-synchronize event templaytes in background
     */
-   private void resyncEventTemplates()
+   private void resyncEventObjects()
    {
       new Thread(new Runnable() {
          @Override
@@ -6173,11 +6173,11 @@ public class NXCSession
          {
             try
             {
-               syncEventTemplates();
+               syncEventObjects();
             }
             catch(Exception e)
             {
-               Logger.error("NXCSession.resyncEventTemplates", "Exception in worker thread", e);
+               Logger.error("NXCSession.resyncEventObjects", "Exception in worker thread", e);
             }
          }
       }).start();
@@ -6188,12 +6188,12 @@ public class NXCSession
     *
     * @return List of event templates cached by client library
     */
-   public EventTemplate[] getCachedEventTemplates()
+   public EventObject[] getCachedEventObjects()
    {
-      EventTemplate[] events = null;
-      synchronized(eventTemplates)
+      EventObject[] events = null;
+      synchronized(eventObjects)
       {
-         events = eventTemplates.values().toArray(new EventTemplate[eventTemplates.size()]);
+         events = eventObjects.values().toArray(new EventObject[eventObjects.size()]);
       }
       return events;
    }
@@ -6201,22 +6201,22 @@ public class NXCSession
    /**
     * Find event template by name in event template database internally
     * maintained by session object. You must call
-    * NXCSession.syncEventTemplates() first to make local copy of event template
+    * NXCSession.syncEventObjects() first to make local copy of event template
     * database.
     *
     * @param name Event name
     * @return Event template object or null if not found
     */
-   public EventTemplate findEventTemplateByName(String name)
+   public EventObject findEventObjectByName(String name)
    {
-      EventTemplate result = null;
-      synchronized(eventTemplates)
+      EventObject result = null;
+      synchronized(eventObjects)
       {
-         for(EventTemplate e : eventTemplates.values())
+         for(EventObject o : eventObjects.values())
          {
-            if (e.getName().equalsIgnoreCase(name))
+            if (o.getName().equalsIgnoreCase(name))
             {
-               result = e;
+               result = o;
                break;
             }
          }
@@ -6232,9 +6232,9 @@ public class NXCSession
     */
    public String getEventName(long code)
    {
-      synchronized(eventTemplates)
+      synchronized(eventObjects)
       {
-         EventTemplate e = eventTemplates.get(code);
+         EventObject e = eventObjects.get(code);
          return (e != null) ? e.getName() : ("[" + Long.toString(code) + "]");
       }
    }
@@ -6242,38 +6242,38 @@ public class NXCSession
    /**
     * Find event template by code in event template database internally
     * maintained by session object. You must call
-    * NXCSession.syncEventTemplates() first to make local copy of event template
+    * NXCSession.syncEventObjects() first to make local copy of event template
     * database.
     *
     * @param code Event code
     * @return Event template object or null if not found
     */
-   public EventTemplate findEventTemplateByCode(long code)
+   public EventObject findEventObjectByCode(long code)
    {
-      synchronized(eventTemplates)
+      synchronized(eventObjects)
       {
-         return eventTemplates.get(code);
+         return eventObjects.get(code);
       }
    }
 
    /**
     * Find multiple event templates by event codes in event template database
     * internally maintained by session object. You must call
-    * NXCSession.syncEventTemplates() first to make local copy of event template
+    * NXCSession.syncEventObjects() first to make local copy of event template
     * database.
     *
     * @param codes List of event codes
     * @return List of found event templates
     */
-   public List<EventTemplate> findMultipleEventTemplates(final Long[] codes)
+   public List<EventObject> findMultipleEventObjects(final Long[] codes)
    {
-      List<EventTemplate> list = new ArrayList<EventTemplate>();
-      synchronized(eventTemplates)
+      List<EventObject> list = new ArrayList<EventObject>();
+      synchronized(eventObjects)
       {
          for(long code : codes)
          {
-            EventTemplate e = eventTemplates.get(code);
-            if (e != null) list.add(e);
+            EventObject o = eventObjects.get(code);
+            if (o != null) list.add(o);
          }
       }
       return list;
@@ -6282,45 +6282,45 @@ public class NXCSession
    /**
     * Find multiple event templates by event codes in event template database
     * internally maintained by session object. You must call
-    * NXCSession.syncEventTemplates() first to make local copy of event template
+    * NXCSession.syncEventObjects() first to make local copy of event template
     * database.
     *
     * @param codes List of event codes
     * @return List of found event templates
     */
-   public List<EventTemplate> findMultipleEventTemplates(final long[] codes)
+   public List<EventObject> findMultipleEventObjects(final long[] codes)
    {
-      List<EventTemplate> list = new ArrayList<EventTemplate>();
-      synchronized(eventTemplates)
+      List<EventObject> list = new ArrayList<EventObject>();
+      synchronized(eventObjects)
       {
          for(long code : codes)
          {
-            EventTemplate e = eventTemplates.get(code);
-            if (e != null) list.add(e);
+            EventObject o = eventObjects.get(code);
+            if (o != null) list.add(o);
          }
       }
       return list;
    }
 
    /**
-    * Get event templates from server
+    * Get event objects from server
     *
-    * @return List of configured event templates
+    * @return List of configured event objects
     * @throws IOException  if socket I/O error occurs
     * @throws NXCException if NetXMS server returns an error or operation was timed out
     */
-   public List<EventTemplate> getEventTemplates() throws IOException, NXCException
+   public List<EventObject> getEventObjects() throws IOException, NXCException
    {
       NXCPMessage msg = newMessage(NXCPCodes.CMD_LOAD_EVENT_DB);
       sendMessage(msg);
-      waitForRCC(msg.getMessageId());
-      ArrayList<EventTemplate> list = new ArrayList<EventTemplate>();
-      while(true)
+      final NXCPMessage response = waitForRCC(msg.getMessageId());
+      int count = response.getFieldAsInt32(NXCPCodes.VID_NUM_EVENTS);
+      long base = NXCPCodes.VID_ELEMENT_LIST_BASE;
+      ArrayList<EventObject> list = new ArrayList<EventObject>();
+      for(int i = 0; i < count; i++)
       {
-         final NXCPMessage response = waitForMessage(NXCPCodes.CMD_EVENT_DB_RECORD, msg.getMessageId());
-         if (response.isEndOfSequence()) 
-            break;
-         list.add(new EventTemplate(response));
+         list.add(EventObject.createFromMessage(response, base));
+         base += 10;
       }
       return list;
    }
@@ -6341,13 +6341,13 @@ public class NXCSession
    }
 
    /**
-    * Delete event template.
+    * Delete event object.
     *
     * @param eventCode Event code
     * @throws IOException  if socket I/O error occurs
     * @throws NXCException if NetXMS server returns an error or operation was timed out
     */
-   public void deleteEventTemplate(long eventCode) throws IOException, NXCException
+   public void deleteEventObject(long eventCode) throws IOException, NXCException
    {
       final NXCPMessage msg = newMessage(NXCPCodes.CMD_DELETE_EVENT_TEMPLATE);
       msg.setFieldInt32(NXCPCodes.VID_EVENT_CODE, (int) eventCode);
@@ -6356,23 +6356,20 @@ public class NXCSession
    }
 
    /**
-    * Modify event template.
+    * Modify event object.
     *
-    * @param evt Event template
+    * @param obj Event Object
+    * @return new event object code
     * @throws IOException  if socket I/O error occurs
     * @throws NXCException if NetXMS server returns an error or operation was timed out
     */
-   public void modifyEventTemplate(EventTemplate evt) throws IOException, NXCException
+   public void modifyEventObject(EventObject obj) throws IOException, NXCException
    {
       final NXCPMessage msg = newMessage(NXCPCodes.CMD_SET_EVENT_INFO);
-      msg.setFieldInt32(NXCPCodes.VID_EVENT_CODE, (int) evt.getCode());
-      msg.setFieldInt32(NXCPCodes.VID_SEVERITY, evt.getSeverity().getValue());
-      msg.setFieldInt32(NXCPCodes.VID_FLAGS, evt.getFlags());
-      msg.setField(NXCPCodes.VID_NAME, evt.getName());
-      msg.setField(NXCPCodes.VID_MESSAGE, evt.getMessage());
-      msg.setField(NXCPCodes.VID_DESCRIPTION, evt.getDescription());
+      obj.fillMessage(msg);
+      
       sendMessage(msg);
-      waitForRCC(msg.getMessageId());
+      obj.setCode(waitForRCC(msg.getMessageId()).getFieldAsInt32(NXCPCodes.VID_EVENT_CODE));
    }
 
    /**
diff --git a/src/java/client/netxms-client/src/main/java/org/netxms/client/events/EventGroup.java b/src/java/client/netxms-client/src/main/java/org/netxms/client/events/EventGroup.java
new file mode 100644 (file)
index 0000000..86af287
--- /dev/null
@@ -0,0 +1,121 @@
+package org.netxms.client.events;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.netxms.base.NXCPCodes;
+import org.netxms.base.NXCPMessage;
+
+public class EventGroup extends EventObject
+{
+   private List<Long> eventCodeList;
+
+   /**
+    * Create new empty event group
+    * 
+    * @param code event code
+    */
+   public EventGroup()
+   {
+      super(0);
+      eventCodeList = new ArrayList<Long>();
+   }
+   
+   /**
+    * Copy constructor
+    * 
+    * @param src Original event group object
+    */
+   public EventGroup(EventGroup src)
+   {
+      super(src);
+      setAll(src);
+   }
+   
+   /**
+    * Create event group from NXCP message
+    * 
+    * @param msg NXCPMessage
+    * @param base base field id
+    */
+   public EventGroup(NXCPMessage msg, long base)
+   {
+      super(msg, base);
+      eventCodeList = new ArrayList<Long>(Arrays.asList(msg.getFieldAsUInt32ArrayEx(base + 4)));
+   }
+   
+   /* (non-Javadoc)
+    * @see org.netxms.client.events.EventObject#fillMessage(org.netxms.base.NXCPMessage)
+    */
+   public void fillMessage(NXCPMessage msg)
+   {
+      super.fillMessage(msg);
+      msg.setField(NXCPCodes.VID_IS_GROUP, true);
+      msg.setField(NXCPCodes.VID_EVENT_LIST, eventCodeList.toArray(new Long[eventCodeList.size()]));
+   }
+   
+   /**
+    * Check if there are any children in the group
+    * 
+    * @return true if there are children in the group
+    */
+   public boolean hasChildren()
+   {
+      return eventCodeList.size() > 0 ? true : false;
+   }
+   
+   /**
+    * Get the array of event codes in the group
+    * 
+    * @return array of event codes in the group
+    */
+   public Long[] getEventCodes()
+   {
+      return eventCodeList.toArray(new Long[eventCodeList.size()]);
+   }
+   
+   /**
+    * Check if event is a child of the group
+    * 
+    * @return true if event is a child
+    */
+   public boolean hasChild(Long code)
+   {
+      return eventCodeList.contains(code);
+   }
+   
+   /** 
+    * Add child to group
+    * 
+    * @param code of child
+    */
+   public void addChild(Long code)
+   {
+      if (this.code != code)
+         eventCodeList.add(code);
+   }
+   
+   /**
+    * Remove child from group
+    * 
+    * @param code of child
+    */
+   public void removeChild(Long code)
+   {
+      eventCodeList.remove(code);
+   }
+   
+   /**
+    * Set all attributes from another event group.
+    * 
+    * @param src Original event group
+    */
+   public void setAll(EventObject src)
+   {
+      if (!(src instanceof EventGroup))
+         return;
+      
+      super.setAll(src);
+      eventCodeList = ((EventGroup)src).eventCodeList;
+   }
+}
diff --git a/src/java/client/netxms-client/src/main/java/org/netxms/client/events/EventObject.java b/src/java/client/netxms-client/src/main/java/org/netxms/client/events/EventObject.java
new file mode 100644 (file)
index 0000000..5c73193
--- /dev/null
@@ -0,0 +1,161 @@
+package org.netxms.client.events;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.netxms.base.NXCPCodes;
+import org.netxms.base.NXCPMessage;
+
+public class EventObject
+{
+   public static final int FLAG_WRITE_TO_LOG = 0x0001;
+   public static final int FLAG_EVENT_GROUP = 0x0002;
+   
+   private static final long GROUP_ID_FLAG = 0x80000000L;
+   
+   protected long code;
+   protected String name;
+   protected String description;
+   protected List<EventGroup> parents;
+   
+   /**
+    * Create either event template or event group from message
+    * 
+    * @param msg NXCPMessage
+    * @param base bas field id
+    * @return EventObject
+    */
+   public static EventObject createFromMessage(NXCPMessage msg, long base)
+   {
+      if ((msg.getFieldAsInt64(base + 1) & GROUP_ID_FLAG) != 0)
+         return new EventGroup(msg, base);
+      else
+         return new EventTemplate(msg, base);
+   }
+   
+   /**
+    * Copy constructor.
+    * 
+    * @param src Original event object
+    */
+   protected EventObject(final EventObject src)
+   {
+      setAll(src);
+   }
+   
+   /**
+    * Create new empty event object
+    * @param code event object code
+    */
+   protected EventObject(long code)
+   {
+      this.code = code;
+      name = "";
+      description = "";
+      parents = new ArrayList<EventGroup>();
+   }
+   
+   /**
+    * Create event object from NXCP message
+    * 
+    * @param msg NXCPMessage
+    * @param base base field id
+    */
+   protected EventObject(final NXCPMessage msg, long base)
+   {
+      code = msg.getFieldAsInt64(base + 1);
+      description = msg.getFieldAsString(base + 2);
+      name = msg.getFieldAsString(base + 3);
+      parents = new ArrayList<EventGroup>();
+   }
+   
+   /**
+    * Fill NXCPMessage with object data
+    * @param msg NXCPMessage
+    */
+   public void fillMessage(NXCPMessage msg)
+   {
+      msg.setFieldInt32(NXCPCodes.VID_EVENT_CODE, (int) code);
+      msg.setField(NXCPCodes.VID_NAME, name);
+      msg.setField(NXCPCodes.VID_DESCRIPTION, description);
+   }
+
+   /**
+    * @return the name
+    */
+   public String getName()
+   {
+      return name;
+   }
+
+   /**
+    * @param name the name to set
+    */
+   public void setName(String name)
+   {
+      this.name = name;
+   }   
+
+   /**
+    * @return the description
+    */
+   public String getDescription()
+   {
+      return description;
+   }
+
+   /**
+    * @param description the description to set
+    */
+   public void setDescription(String description)
+   {
+      this.description = description;
+   }   
+
+   /**
+    * @return the code
+    */
+   public long getCode()
+   {
+      return code;
+   }
+
+   /**
+    * @param code the code to set
+    */
+   public void setCode(long code)
+   {
+      this.code = code;
+   }
+
+   /**
+    * Set all attributes from another event object.
+    * 
+    * @param src Original event object
+    */
+   public void setAll(EventObject src)
+   {
+      code = src.code;
+      name = src.name;
+      description = src.description;
+   }
+   
+   /**
+    * Add parent group to object
+    * @param parent group
+    */
+   public void addParent(EventGroup parent)
+   {
+      if (!equals(parent))
+         parents.add(parent);
+   }
+   
+   /**
+    * Check if object has parents
+    * 
+    * @return true if object has parents
+    */
+   public boolean hasParents()
+   {
+      return !parents.isEmpty();
+   }
+}
index 4dacda2..ed7a6c6 100644 (file)
@@ -25,16 +25,11 @@ import org.netxms.client.constants.Severity;
 /**
  * Event template
  */
-public class EventTemplate
+public class EventTemplate extends EventObject
 {
-       public static final int FLAG_WRITE_TO_LOG = 0x0001;
-       
-       private long code;
-       private String name;
        private Severity severity;
        private int flags;
        private String message;
-       private String description;
        
        /**
         * Create new empty event template.
@@ -43,27 +38,24 @@ public class EventTemplate
         */
        public EventTemplate(long code)
        {
-               this.code = code;
-               name = "";
+          super(code);
                severity = Severity.NORMAL;
                flags = FLAG_WRITE_TO_LOG;
                message = "";
-               description = "";
        }
        
        /**
         * Create event template object from NXCP message.
         * 
         * @param msg NXCP message
+    * @param base base field id
         */
-       public EventTemplate(final NXCPMessage msg)
+       public EventTemplate(final NXCPMessage msg, long base)
        {
-               code = msg.getFieldAsInt64(NXCPCodes.VID_EVENT_CODE);
-               severity = Severity.getByValue(msg.getFieldAsInt32(NXCPCodes.VID_SEVERITY));
-               flags = msg.getFieldAsInt32(NXCPCodes.VID_FLAGS);
-               name = msg.getFieldAsString(NXCPCodes.VID_NAME);
-               message = msg.getFieldAsString(NXCPCodes.VID_MESSAGE);
-               description = msg.getFieldAsString(NXCPCodes.VID_DESCRIPTION);
+          super(msg, base);
+               severity = Severity.getByValue(msg.getFieldAsInt32(base + 4));
+               flags = msg.getFieldAsInt32(base + 5);
+               message = msg.getFieldAsString(base + 6);
        }
        
        /**
@@ -73,38 +65,35 @@ public class EventTemplate
         */
        public EventTemplate(final EventTemplate src)
        {
+          super(src);
                setAll(src);
        }
        
-       /**
-        * Set all attributes from another event template object.
-        * 
-        * @param src Original event template object
-        */
-       public void setAll(final EventTemplate src)
-       {
-               code = src.code;
-               severity = src.severity;
-               flags = src.flags;
-               name = src.name;
-               message = src.message;
-               description = src.description;
-       }
-
-       /**
-        * @return the name
+       /* (non-Javadoc)
+        * @see org.netxms.client.events.EventObject#fillMessage(org.netxms.base.NXCPMessage)
         */
-       public String getName()
+       public void fillMessage(NXCPMessage msg)
        {
-               return name;
+          super.fillMessage(msg);
+      msg.setFieldInt32(NXCPCodes.VID_SEVERITY, severity.getValue());
+      msg.setFieldInt32(NXCPCodes.VID_FLAGS, flags);
+      msg.setField(NXCPCodes.VID_MESSAGE, message);
        }
-
+       
        /**
-        * @param name the name to set
+        * Set all attributes from another event template object.
+        * 
+        * @param src Original event template object
         */
-       public void setName(String name)
+       public void setAll(final EventObject src)
        {
-               this.name = name;
+          if (!(src instanceof EventTemplate))
+             return;
+          
+          super.setAll(src);
+               severity = ((EventTemplate)src).severity;
+               flags = ((EventTemplate)src).flags;
+               message = ((EventTemplate)src).message;
        }
 
        /**
@@ -154,36 +143,4 @@ public class EventTemplate
        {
                this.message = message;
        }
-
-       /**
-        * @return the description
-        */
-       public String getDescription()
-       {
-               return description;
-       }
-
-       /**
-        * @param description the description to set
-        */
-       public void setDescription(String description)
-       {
-               this.description = description;
-       }
-
-       /**
-        * @return the code
-        */
-       public long getCode()
-       {
-               return code;
-       }
-
-       /**
-        * @param code the code to set
-        */
-       public void setCode(long code)
-       {
-               this.code = code;
-       }
 }
index e19f274..54836a7 100644 (file)
@@ -92,7 +92,7 @@ public class ConnectionTest extends AbstractSessionTest
                   final NXCSession session = connect(true);
                   
                   session.syncObjects();
-                  session.syncEventTemplates();
+                  session.syncEventObjects();
                   session.syncUserDatabase();
 
                   Thread.sleep(rand.nextInt(60000) + 10000);
index 3e115b9..94a45e2 100644 (file)
@@ -27,9 +27,9 @@ public class EventDatabaseSyncTest extends AbstractSessionTest
        {
                final NXCSession session = connect();
                
-               assertNull(session.findEventTemplateByCode(1L));
-               session.syncEventTemplates();
-               assertNotNull(session.findEventTemplateByCode(1L));
+               assertNull(session.findEventObjectByCode(1L));
+               session.syncEventObjects();
+               assertNotNull(session.findEventObjectByCode(1L));
                
                session.disconnect();
        }
diff --git a/src/java/netxms-eclipse/Core/icons/container.png b/src/java/netxms-eclipse/Core/icons/container.png
new file mode 100644 (file)
index 0000000..784e8fa
Binary files /dev/null and b/src/java/netxms-eclipse/Core/icons/container.png differ
index a1f8da8..327d21f 100644 (file)
@@ -37,6 +37,7 @@ public class SharedIcons
        public static ImageDescriptor CLOSE;
        public static ImageDescriptor COLLAPSE;
        public static ImageDescriptor COLLAPSE_ALL;
+   public static ImageDescriptor CONTAINER;
        public static ImageDescriptor COPY;
        public static ImageDescriptor CSV;
    public static ImageDescriptor CUT;
@@ -76,6 +77,7 @@ public class SharedIcons
        public static Image IMG_CLOSE;
        public static Image IMG_COLLAPSE;
        public static Image IMG_COLLAPSE_ALL;
+   public static Image IMG_CONTAINER;
        public static Image IMG_COPY;
        public static Image IMG_CSV;
    public static Image IMG_CUT;
@@ -120,6 +122,7 @@ public class SharedIcons
                CLOSE = Activator.getImageDescriptor("icons/close.gif"); //$NON-NLS-1$
                COLLAPSE = Activator.getImageDescriptor("icons/collapse.png"); //$NON-NLS-1$
                COLLAPSE_ALL = Activator.getImageDescriptor("icons/collapseall.png"); //$NON-NLS-1$
+               CONTAINER = Activator.getImageDescriptor("icons/container.png"); //$NON-NLS-1$
                COPY = Activator.getImageDescriptor("icons/copy.gif"); //$NON-NLS-1$
                CSV = Activator.getImageDescriptor("icons/csv.png"); //$NON-NLS-1$
       CUT = Activator.getImageDescriptor("icons/cut.gif"); //$NON-NLS-1$
@@ -159,6 +162,7 @@ public class SharedIcons
                IMG_CLOSE = CLOSE.createImage();
                IMG_COLLAPSE = COLLAPSE.createImage();
                IMG_COLLAPSE_ALL = COLLAPSE_ALL.createImage();
+               IMG_CONTAINER = CONTAINER.createImage();
                IMG_COPY = COPY.createImage();
                IMG_CSV = CSV.createImage();
       IMG_CUT = CUT.createImage();
index 3b0998f..86eb867 100644 (file)
@@ -130,7 +130,7 @@ public class LoginJob implements IRunnableWithProgress
          monitor.setTaskName(Messages.get().LoginJob_sync_event_db);
          try
          {
-            session.syncEventTemplates();
+            session.syncEventObjects();
          }
          catch(NXCException e)
          {
index 6cbc244..3825a6e 100644 (file)
@@ -53,7 +53,7 @@ public class ThresholdLabelProvider extends LabelProvider implements ITableLabel
                        case Thresholds.COLUMN_OPERATION:
                                return thresholdIcon;
                        case Thresholds.COLUMN_EVENT:
-                               final EventTemplate event = session.findEventTemplateByCode(((Threshold)element).getFireEvent());
+                               final EventTemplate event = (EventTemplate)session.findEventObjectByCode(((Threshold)element).getFireEvent());
                                return StatusDisplayInfo.getStatusImage((event != null) ? event.getSeverity() : Severity.UNKNOWN);
                }
                return null;
@@ -80,7 +80,7 @@ public class ThresholdLabelProvider extends LabelProvider implements ITableLabel
                                }
                                return text.toString();
                        case Thresholds.COLUMN_EVENT:
-                               final EventTemplate event = session.findEventTemplateByCode(((Threshold)element).getFireEvent());
+                               final EventTemplate event = (EventTemplate)session.findEventObjectByCode(((Threshold)element).getFireEvent());
                                return eventLabelProvider.getText(event);
                }
                return null;
index 06b3e32..6a4ce09 100644 (file)
@@ -51,12 +51,12 @@ public class TableThresholdLabelProvider extends LabelProvider implements ITable
                                return thresholdIcon;
                        case 2:
                        {
-                               final EventTemplate event = session.findEventTemplateByCode(((TableThreshold)element).getActivationEvent());
+                               final EventTemplate event = (EventTemplate)session.findEventObjectByCode(((TableThreshold)element).getActivationEvent());
                                return StatusDisplayInfo.getStatusImage((event != null) ? event.getSeverity() : Severity.UNKNOWN);
                        }
                        case 3:
                        {
-                               final EventTemplate event = session.findEventTemplateByCode(((TableThreshold)element).getDeactivationEvent());
+                               final EventTemplate event = (EventTemplate)session.findEventObjectByCode(((TableThreshold)element).getDeactivationEvent());
                                return StatusDisplayInfo.getStatusImage((event != null) ? event.getSeverity() : Severity.UNKNOWN);
                        }
                }
@@ -77,12 +77,12 @@ public class TableThresholdLabelProvider extends LabelProvider implements ITable
                           return Integer.toString(((TableThreshold)element).getSampleCount());
                        case 2:
                        {
-                               final EventTemplate event = session.findEventTemplateByCode(((TableThreshold)element).getActivationEvent());
+                               final EventTemplate event = (EventTemplate)session.findEventObjectByCode(((TableThreshold)element).getActivationEvent());
                                return eventLabelProvider.getText(event);
                        }
                        case 3:
                        {
-                               final EventTemplate event = session.findEventTemplateByCode(((TableThreshold)element).getDeactivationEvent());
+                               final EventTemplate event = (EventTemplate)session.findEventObjectByCode(((TableThreshold)element).getDeactivationEvent());
                                return eventLabelProvider.getText(event);
                        }
                }
index 0a9ac05..d644203 100644 (file)
@@ -22,7 +22,6 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
-
 import org.eclipse.jface.viewers.ArrayContentProvider;
 import org.eclipse.jface.viewers.ILabelProvider;
 import org.eclipse.jface.viewers.ISelectionChangedListener;
@@ -40,11 +39,11 @@ import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.ui.dialogs.PropertyPage;
-import org.eclipse.ui.model.WorkbenchLabelProvider;
 import org.netxms.client.NXCSession;
+import org.netxms.client.events.EventObject;
 import org.netxms.client.events.EventProcessingPolicyRule;
-import org.netxms.client.events.EventTemplate;
 import org.netxms.ui.eclipse.epp.Messages;
+import org.netxms.ui.eclipse.epp.propertypages.helpers.EventObjectLabelProvider;
 import org.netxms.ui.eclipse.epp.widgets.RuleEditor;
 import org.netxms.ui.eclipse.eventmanager.dialogs.EventSelectionDialog;
 import org.netxms.ui.eclipse.shared.ConsoleSharedData;
@@ -61,7 +60,7 @@ public class RuleEvents extends PropertyPage
        private RuleEditor editor;
        private EventProcessingPolicyRule rule;
        private SortableTableViewer viewer;
-       private Map<Long, EventTemplate> events = new HashMap<Long, EventTemplate>();
+       private Map<Long, EventObject> events = new HashMap<Long, EventObject>();
        private Button addButton;
        private Button deleteButton;
        private Button checkInverted;
@@ -91,7 +90,7 @@ public class RuleEvents extends PropertyPage
       final int[] columnWidths = { 300 };
       viewer = new SortableTableViewer(dialogArea, columnNames, columnWidths, 0, SWT.UP, SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION);
       viewer.setContentProvider(new ArrayContentProvider());
-      viewer.setLabelProvider(new WorkbenchLabelProvider());
+      viewer.setLabelProvider(new EventObjectLabelProvider());
       viewer.setComparator(new ObjectLabelComparator((ILabelProvider)viewer.getLabelProvider()));
       viewer.addSelectionChangedListener(new ISelectionChangedListener() {
                        @Override
@@ -102,8 +101,8 @@ public class RuleEvents extends PropertyPage
                        }
       });
 
-      for(EventTemplate e : session.findMultipleEventTemplates(rule.getEvents().toArray(new Long[0])))
-       events.put(e.getCode(), e);
+      for(EventObject o : session.findMultipleEventObjects(rule.getEvents().toArray(new Long[0])))
+       events.put(o.getCode(), o);
       viewer.setInput(events.values().toArray());
       
       GridData gridData = new GridData();
@@ -172,11 +171,11 @@ public class RuleEvents extends PropertyPage
         */
        private void addEvent()
        {
-               EventSelectionDialog dlg = new EventSelectionDialog(getShell());
+               EventSelectionDialog dlg = new EventSelectionDialog(getShell(), true);
                dlg.enableMultiSelection(true);
                if (dlg.open() == Window.OK)
                {
-                       for(EventTemplate e : dlg.getSelectedEvents())
+                       for(EventObject e : dlg.getSelectedEvents())
                                events.put(e.getCode(), e);
                }
       viewer.setInput(events.values().toArray());
@@ -193,7 +192,7 @@ public class RuleEvents extends PropertyPage
                {
                        while(it.hasNext())
                        {
-                               EventTemplate e = (EventTemplate)it.next();
+                          EventObject e = (EventObject)it.next();
                                events.remove(e.getCode());
                        }
              viewer.setInput(events.values().toArray());
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-package org.netxms.ui.eclipse.eventmanager.views.helpers;
+package org.netxms.ui.eclipse.epp.propertypages.helpers;
 
+import org.eclipse.jface.viewers.ITableColorProvider;
 import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.swt.graphics.Color;
 import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
 import org.eclipse.ui.model.WorkbenchLabelProvider;
-import org.netxms.client.events.EventTemplate;
-import org.netxms.ui.eclipse.console.resources.StatusDisplayInfo;
-import org.netxms.ui.eclipse.eventmanager.views.EventConfigurator;
+import org.netxms.client.events.EventGroup;
+import org.netxms.client.events.EventObject;
+import org.netxms.ui.eclipse.console.resources.SharedIcons;
 
 /**
  * Label provider for event template objects
  */
-public class EventTemplateLabelProvider extends WorkbenchLabelProvider implements ITableLabelProvider
+public class EventObjectLabelProvider extends WorkbenchLabelProvider implements ITableLabelProvider, ITableColorProvider
 {
+   private static final Color COLOR_GROUP = new Color(Display.getDefault(), new RGB(255, 221, 173));
        /* (non-Javadoc)
         * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int)
         */
        @Override
        public Image getColumnImage(Object element, int columnIndex)
        {
-               return (columnIndex == 0) ? getImage(element) : null;
+          if ((columnIndex != 0))
+             return null;
+          if (element instanceof EventGroup)
+             return SharedIcons.IMG_CONTAINER;
+               return getImage(element);
        }
 
        /* (non-Javadoc)
@@ -45,21 +54,20 @@ public class EventTemplateLabelProvider extends WorkbenchLabelProvider implement
        @Override
        public String getColumnText(Object element, int columnIndex)
        {
-               switch(columnIndex)
-               {
-                       case EventConfigurator.COLUMN_CODE:
-                               return Long.toString(((EventTemplate)element).getCode());
-                       case EventConfigurator.COLUMN_NAME:
-                               return getText(element);
-                       case EventConfigurator.COLUMN_SEVERITY:
-                               return StatusDisplayInfo.getStatusText(((EventTemplate)element).getSeverity());
-                       case EventConfigurator.COLUMN_FLAGS:
-                               return ((((EventTemplate)element).getFlags() & EventTemplate.FLAG_WRITE_TO_LOG) != 0) ? "L" : "-"; //$NON-NLS-1$ //$NON-NLS-2$
-                       case EventConfigurator.COLUMN_MESSAGE:
-                               return ((EventTemplate)element).getMessage();
-                       case EventConfigurator.COLUMN_DESCRIPTION:
-                               return ((EventTemplate)element).getDescription();
-               }
-               return null;
+          return ((EventObject)element).getName();     
        }
+
+   @Override
+   public Color getForeground(Object element, int columnIndex)
+   {
+      return null;
+   }
+
+   @Override
+   public Color getBackground(Object element, int columnIndex)
+   {
+      if (element instanceof EventGroup)
+         return COLOR_GROUP;
+      return null;
+   }
 }
index 1e3e65c..7343428 100644 (file)
@@ -62,6 +62,7 @@ import org.netxms.client.ServerAction;
 import org.netxms.client.SessionListener;
 import org.netxms.client.SessionNotification;
 import org.netxms.client.events.AlarmCategory;
+import org.netxms.client.events.EventObject;
 import org.netxms.client.events.EventProcessingPolicy;
 import org.netxms.client.events.EventProcessingPolicyRule;
 import org.netxms.client.events.EventTemplate;
@@ -1291,8 +1292,8 @@ public class EventProcessingPolicyEditor extends ViewPart implements ISaveablePa
       // check event names
       for(Long code : rule.getEvents())
       {
-         EventTemplate evt = session.findEventTemplateByCode(code);
-         if ((evt != null) && evt.getName().toLowerCase().contains(filterText))
+         EventObject evo = session.findEventObjectByCode(code);
+         if ((evo != null) && evo.getName().toLowerCase().contains(filterText))
             return true;
       }
 
index bd1bb56..7cb1e31 100644 (file)
@@ -66,6 +66,7 @@ import org.netxms.client.NXCSession;
 import org.netxms.client.ServerAction;
 import org.netxms.client.constants.Severity;
 import org.netxms.client.events.AlarmCategory;
+import org.netxms.client.events.EventObject;
 import org.netxms.client.events.EventProcessingPolicyRule;
 import org.netxms.client.events.EventTemplate;
 import org.netxms.client.objects.AbstractObject;
@@ -542,32 +543,35 @@ public class RuleEditor extends Composite
          final MouseListener listener = createMouseListener("org.netxms.ui.eclipse.epp.propertypages.RuleEvents#10"); //$NON-NLS-1$
          addConditionGroupLabel(clientArea, Messages.get().RuleEditor_EventIs, needAnd, rule.isEventsInverted(), listener);
 
-         List<EventTemplate> sortedEvents = new ArrayList<EventTemplate>(rule.getEvents().size());
+         List<EventObject> sortedEvents = new ArrayList<EventObject>(rule.getEvents().size());
          for(Long code : rule.getEvents())
          {
-            EventTemplate event = session.findEventTemplateByCode(code);
+            EventObject event = session.findEventObjectByCode(code);
             if (event == null)
             {
                event = new EventTemplate(code);
-               event.setSeverity(Severity.UNKNOWN);
+               ((EventTemplate)event).setSeverity(Severity.UNKNOWN);
                event.setName("<" + code.toString() + ">"); //$NON-NLS-1$ //$NON-NLS-2$
             }
             sortedEvents.add(event);
          }
-         Collections.sort(sortedEvents, new Comparator<EventTemplate>() {
+         Collections.sort(sortedEvents, new Comparator<EventObject>() {
             @Override
-            public int compare(EventTemplate t1, EventTemplate t2)
+            public int compare(EventObject t1, EventObject t2)
             {
                return t1.getName().compareToIgnoreCase(t2.getName());
             }
          });
 
-         for(EventTemplate e : sortedEvents)
+         for(EventObject e : sortedEvents)
          {
             CLabel clabel = createCLabel(clientArea, 2, false);
             clabel.addMouseListener(listener);
             clabel.setText(e.getName());
-            clabel.setImage(StatusDisplayInfo.getStatusImage(e.getSeverity()));
+            if (e instanceof EventTemplate)
+               clabel.setImage(StatusDisplayInfo.getStatusImage(((EventTemplate)e).getSeverity()));
+            else
+               clabel.setImage(SharedIcons.IMG_CONTAINER);
          }
          needAnd = true;
       }
diff --git a/src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/dialogs/EditEventGroupDialog.java b/src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/dialogs/EditEventGroupDialog.java
new file mode 100644 (file)
index 0000000..d48f2a6
--- /dev/null
@@ -0,0 +1,106 @@
+/**
+ * NetXMS - open source network management system
+ * Copyright (C) 2003-2017 Raden Solutions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.netxms.ui.eclipse.eventmanager.dialogs;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.netxms.client.events.EventGroup;
+import org.netxms.ui.eclipse.eventmanager.Messages;
+import org.netxms.ui.eclipse.tools.WidgetHelper;
+import org.netxms.ui.eclipse.widgets.LabeledText;
+
+public class EditEventGroupDialog  extends Dialog
+{
+   private LabeledText name;
+   private LabeledText description;
+   private EventGroup group;
+
+   public EditEventGroupDialog(Shell parentShell, EventGroup group)
+   {
+      super(parentShell);
+      this.group = group;
+   }
+
+   /* (non-Javadoc)
+    * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
+    */
+   @Override
+   protected Control createDialogArea(Composite parent)
+   {
+      Composite dialogArea = (Composite)super.createDialogArea(parent);
+
+      GridLayout layout = new GridLayout();
+      layout.marginWidth = WidgetHelper.DIALOG_WIDTH_MARGIN;
+      layout.marginHeight = WidgetHelper.DIALOG_HEIGHT_MARGIN;
+      layout.horizontalSpacing = WidgetHelper.OUTER_SPACING * 2;
+      dialogArea.setLayout(layout);
+            
+      GridData gd = new GridData();
+      gd.horizontalAlignment = SWT.FILL;
+      
+      name = new LabeledText(dialogArea, SWT.NONE);
+      name.setLabel("Name");
+      name.setText(group.getName());
+      name.getTextControl().setTextLimit(63);
+      gd = new GridData();
+      gd.grabExcessHorizontalSpace = true;
+      gd.horizontalAlignment = SWT.FILL;
+      name.setLayoutData(gd);
+      
+      description = new LabeledText(dialogArea, SWT.NONE, SWT.MULTI | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.WRAP);
+      description.setLabel(Messages.get().EditEventTemplateDialog_Description);
+      description.setText(group.getDescription());
+      description.getTextControl().setTextLimit(254);
+      gd = new GridData();
+      gd.grabExcessHorizontalSpace = true;
+      gd.horizontalAlignment = SWT.FILL;
+      gd.heightHint = 200;
+      gd.widthHint = 450;
+      gd.verticalAlignment = SWT.FILL;
+      description.setLayoutData(gd);
+
+      return dialogArea;
+   }
+
+   /* (non-Javadoc)
+    * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
+    */
+   @Override
+   protected void configureShell(Shell newShell)
+   {
+      super.configureShell(newShell);
+      newShell.setText("Create event group");
+   }
+
+   /* (non-Javadoc)
+    * @see org.eclipse.jface.dialogs.Dialog#okPressed()
+    */
+   @Override
+   protected void okPressed()
+   {
+      group.setName(name.getText());
+      group.setDescription(description.getText());
+      super.okPressed();
+   }
+}
index 2f9ba8f..d414a07 100644 (file)
@@ -21,30 +21,20 @@ package org.netxms.ui.eclipse.eventmanager.dialogs;
 import java.util.List;
 import org.eclipse.jface.dialogs.Dialog;
 import org.eclipse.jface.dialogs.IDialogSettings;
-import org.eclipse.jface.viewers.ArrayContentProvider;
 import org.eclipse.jface.viewers.DoubleClickEvent;
 import org.eclipse.jface.viewers.IDoubleClickListener;
 import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.TableViewer;
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Shell;
-import org.netxms.client.events.EventTemplate;
+import org.netxms.client.events.EventObject;
 import org.netxms.ui.eclipse.eventmanager.Activator;
 import org.netxms.ui.eclipse.eventmanager.Messages;
-import org.netxms.ui.eclipse.eventmanager.dialogs.helpers.EventListFilter;
-import org.netxms.ui.eclipse.eventmanager.views.helpers.EventTemplateComparator;
-import org.netxms.ui.eclipse.eventmanager.views.helpers.EventTemplateLabelProvider;
-import org.netxms.ui.eclipse.shared.ConsoleSharedData;
-import org.netxms.ui.eclipse.tools.WidgetHelper;
-import org.netxms.ui.eclipse.widgets.FilterText;
-import org.netxms.ui.eclipse.widgets.SortableTableViewer;
+import org.netxms.ui.eclipse.eventmanager.widgets.EventObjectList;
 
 /**
  * Event selection dialog
@@ -52,20 +42,22 @@ import org.netxms.ui.eclipse.widgets.SortableTableViewer;
  */
 public class EventSelectionDialog extends Dialog
 {
+   private static final String TABLE_CONFIG_PREFIX = "SelectEvent"; //$NON-NLS-1$
+   
        private boolean multiSelection;
-       private FilterText filterText;
-       private TableViewer eventList;
-       private EventTemplate selectedEvents[];
-       private EventListFilter filter;
+   private boolean showGroups;
+       private EventObject selectedEvents[];
+       private EventObjectList eventObjectList;
 
        /**
         * @param parentShell
         */
-       public EventSelectionDialog(Shell parentShell)
+       public EventSelectionDialog(Shell parentShell, boolean showGroups)
        {
                super(parentShell);
                setShellStyle(getShellStyle() | SWT.RESIZE);
                multiSelection = false;
+               this.showGroups = showGroups;
        }
 
        /* (non-Javadoc)
@@ -79,7 +71,7 @@ public class EventSelectionDialog extends Dialog
                IDialogSettings settings = Activator.getDefault().getDialogSettings();
                try
                {
-                       newShell.setSize(settings.getInt("SelectEvent.cx"), settings.getInt("SelectEvent.cy")); //$NON-NLS-1$ //$NON-NLS-2$
+                       newShell.setSize(settings.getInt(TABLE_CONFIG_PREFIX + ".cx"), settings.getInt(TABLE_CONFIG_PREFIX + ".cy")); //$NON-NLS-1$ //$NON-NLS-2$
                }
                catch(NumberFormatException e)
                {
@@ -92,56 +84,19 @@ public class EventSelectionDialog extends Dialog
        @Override
        protected Control createDialogArea(Composite parent)
        {
-               IDialogSettings settings = Activator.getDefault().getDialogSettings();
                Composite dialogArea = (Composite)super.createDialogArea(parent);
                
-               GridLayout layout = new GridLayout();
-      layout.marginWidth = WidgetHelper.DIALOG_WIDTH_MARGIN;
-      layout.marginHeight = WidgetHelper.DIALOG_HEIGHT_MARGIN;
-      layout.horizontalSpacing = WidgetHelper.OUTER_SPACING;
-               layout.numColumns = 2;
-               dialogArea.setLayout(layout);
-               
-               filterText = new FilterText(dialogArea, SWT.NONE, null, false);
-               GridData gd = new GridData();
-               gd.grabExcessHorizontalSpace = true;
-               gd.horizontalAlignment = SWT.FILL;
-               filterText.setLayoutData(gd);
-               final String filterString = settings.get("SelectEvent.Filter"); //$NON-NLS-1$
-               if (filterString != null)
-                       filterText.setText(filterString);
-               
-               final String[] names = { Messages.get().EventSelectionDialog_Code, Messages.get().EventSelectionDialog_Name };
-               final int[] widths = { 80, 350 };
-               eventList = new SortableTableViewer(dialogArea, names, widths, 1, SWT.UP, 
-                               SWT.BORDER | SWT.FULL_SELECTION | (multiSelection ? SWT.MULTI : SWT.SINGLE) | SWT.H_SCROLL | SWT.V_SCROLL);
-               eventList.setContentProvider(new ArrayContentProvider());
-               eventList.setComparator(new EventTemplateComparator());
-               eventList.setLabelProvider(new EventTemplateLabelProvider());
-               filter = new EventListFilter();
-               if (filterString != null)
-                       filter.setFilterString(filterString);
-               eventList.addFilter(filter);
-               eventList.setInput(ConsoleSharedData.getSession().getCachedEventTemplates());
-               gd = new GridData();
-               gd.grabExcessHorizontalSpace = true;
-               gd.horizontalAlignment = SWT.FILL;
-               gd.horizontalSpan = 2;
-               gd.verticalAlignment = SWT.FILL;
-               gd.grabExcessVerticalSpace = true;
-               gd.heightHint = 350;
-               eventList.getTable().setLayoutData(gd);
+               dialogArea.setLayout(new FormLayout());
                
-               filterText.addModifyListener(new ModifyListener() {
-                       @Override
-                       public void modifyText(ModifyEvent e)
-                       {
-                               filter.setFilterString(filterText.getText());
-                               eventList.refresh();
-                       }
-               });
+               eventObjectList = new EventObjectList(dialogArea, SWT.NONE, TABLE_CONFIG_PREFIX, true, showGroups);
+               FormData fd = new FormData();
+      fd.left = new FormAttachment(0, 0);
+      fd.top = new FormAttachment(100, 0);
+      fd.right = new FormAttachment(100, 0);
+      fd.bottom = new FormAttachment(100, 0);
+      eventObjectList.setLayoutData(fd);
                
-               eventList.addDoubleClickListener(new IDoubleClickListener() {
+      eventObjectList.getViewer().addDoubleClickListener(new IDoubleClickListener() {
                        @Override
                        public void doubleClick(DoubleClickEvent event)
                        {
@@ -149,46 +104,21 @@ public class EventSelectionDialog extends Dialog
                        }
                });
                
-               filterText.setFocus();
                return dialogArea;
        }
        
        /* (non-Javadoc)
-        * @see org.eclipse.jface.dialogs.Dialog#cancelPressed()
-        */
-       @Override
-       protected void cancelPressed()
-       {
-               saveSettings();
-               super.cancelPressed();
-       }
-
-       /* (non-Javadoc)
         * @see org.eclipse.jface.dialogs.Dialog#okPressed()
         */
        @SuppressWarnings("unchecked")
        @Override
        protected void okPressed()
        {
-               final IStructuredSelection selection = (IStructuredSelection)eventList.getSelection();
-               final List<EventTemplate> list = selection.toList();
-               selectedEvents = list.toArray(new EventTemplate[list.size()]);
-               saveSettings();
+               final IStructuredSelection selection = (IStructuredSelection)eventObjectList.getViewer().getSelection();
+               final List<EventObject> list = selection.toList();
+               selectedEvents = list.toArray(new EventObject[list.size()]);
                super.okPressed();
        }
-       
-       /**
-        * Save dialog settings
-        */
-       private void saveSettings()
-       {
-               Point size = getShell().getSize();
-               IDialogSettings settings = Activator.getDefault().getDialogSettings();
-
-               settings.put("SelectEvent.cx", size.x); //$NON-NLS-1$
-               settings.put("SelectEvent.cy", size.y); //$NON-NLS-1$
-               settings.put("SelectEvent.Filter", filterText.getText()); //$NON-NLS-1$
-       }
 
        /**
         * @return true if multiple event selection is enabled
@@ -213,7 +143,7 @@ public class EventSelectionDialog extends Dialog
         * 
         * @return Selected event templates
         */
-       public EventTemplate[] getSelectedEvents()
+       public EventObject[] getSelectedEvents()
        {
                return selectedEvents;
        }
index 0394b33..677140a 100644 (file)
@@ -20,7 +20,7 @@ package org.netxms.ui.eclipse.eventmanager.dialogs.helpers;
 
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.jface.viewers.ViewerFilter;
-import org.netxms.client.events.EventTemplate;
+import org.netxms.client.events.EventObject;
 
 /**
  * Filter for event list
@@ -39,7 +39,7 @@ public class EventListFilter extends ViewerFilter
                if (filterString == null)
                        return true;
                
-               return ((EventTemplate)element).getName().toLowerCase().contains(filterString);
+               return ((EventObject)element).getName().toLowerCase().contains(filterString);
        }
 
        /**
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-package org.netxms.ui.eclipse.eventmanager.views.helpers;
+package org.netxms.ui.eclipse.eventmanager.dialogs.helpers;
 
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.jface.viewers.ViewerComparator;
 import org.eclipse.swt.SWT;
-import org.netxms.client.events.EventTemplate;
-import org.netxms.ui.eclipse.eventmanager.views.EventConfigurator;
+import org.netxms.client.events.EventObject;
+import org.netxms.ui.eclipse.eventmanager.widgets.EventObjectList;
 import org.netxms.ui.eclipse.widgets.SortableTableViewer;
 
 /**
  * Event template comparator
  */
-public class EventTemplateComparator extends ViewerComparator
+public class EventObjectComparator extends ViewerComparator
 {
        /* (non-Javadoc)
         * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
@@ -40,23 +40,11 @@ public class EventTemplateComparator extends ViewerComparator
 
                switch((Integer)((SortableTableViewer)viewer).getTable().getSortColumn().getData("ID")) //$NON-NLS-1$
                {
-                       case EventConfigurator.COLUMN_CODE:
-                               result = (int)(((EventTemplate)e1).getCode() - ((EventTemplate)e2).getCode());
+                       case EventObjectList.COLUMN_CODE:
+                               result = (int)(((EventObject)e1).getCode() - ((EventObject)e2).getCode());
                                break;
-                       case EventConfigurator.COLUMN_NAME:
-                               result = ((EventTemplate)e1).getName().compareToIgnoreCase(((EventTemplate)e2).getName());
-                               break;
-                       case EventConfigurator.COLUMN_SEVERITY:
-                               result = ((EventTemplate)e1).getSeverity().compareTo(((EventTemplate)e2).getSeverity());
-                               break;
-                       case EventConfigurator.COLUMN_FLAGS:
-                               result = ((EventTemplate)e1).getFlags() - ((EventTemplate)e2).getFlags();
-                               break;
-                       case EventConfigurator.COLUMN_MESSAGE:
-                               result = ((EventTemplate)e1).getMessage().compareToIgnoreCase(((EventTemplate)e2).getMessage());
-                               break;
-                       case EventConfigurator.COLUMN_DESCRIPTION:
-                               result = ((EventTemplate)e1).getDescription().compareToIgnoreCase(((EventTemplate)e2).getDescription());
+                       case EventObjectList.COLUMN_NAME:
+                               result = ((EventObject)e1).getName().compareToIgnoreCase(((EventObject)e2).getName());
                                break;
                        default:
                                result = 0;
index 18bd8ad..b529c74 100644 (file)
  */
 package org.netxms.ui.eclipse.eventmanager.views;
 
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.jface.action.Action;
 import org.eclipse.jface.action.GroupMarker;
-import org.eclipse.jface.action.IMenuListener;
 import org.eclipse.jface.action.IMenuManager;
 import org.eclipse.jface.action.IToolBarManager;
-import org.eclipse.jface.action.MenuManager;
 import org.eclipse.jface.action.Separator;
-import org.eclipse.jface.commands.ActionHandler;
-import org.eclipse.jface.dialogs.IDialogSettings;
-import org.eclipse.jface.viewers.ArrayContentProvider;
 import org.eclipse.jface.viewers.DoubleClickEvent;
 import org.eclipse.jface.viewers.IDoubleClickListener;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.jface.window.Window;
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
 import org.eclipse.swt.layout.FormAttachment;
 import org.eclipse.swt.layout.FormData;
 import org.eclipse.swt.layout.FormLayout;
 import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Menu;
-import org.eclipse.swt.widgets.Shell;
 import org.eclipse.ui.IActionBars;
-import org.eclipse.ui.IViewSite;
 import org.eclipse.ui.IWorkbenchActionConstants;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.contexts.IContextService;
-import org.eclipse.ui.handlers.IHandlerService;
 import org.eclipse.ui.part.ViewPart;
-import org.netxms.client.NXCSession;
-import org.netxms.client.SessionListener;
-import org.netxms.client.SessionNotification;
-import org.netxms.client.events.EventTemplate;
-import org.netxms.ui.eclipse.actions.RefreshAction;
-import org.netxms.ui.eclipse.console.resources.SharedIcons;
-import org.netxms.ui.eclipse.eventmanager.Activator;
-import org.netxms.ui.eclipse.eventmanager.Messages;
-import org.netxms.ui.eclipse.eventmanager.dialogs.EditEventTemplateDialog;
-import org.netxms.ui.eclipse.eventmanager.views.helpers.EventTemplateComparator;
-import org.netxms.ui.eclipse.eventmanager.views.helpers.EventTemplateFilter;
-import org.netxms.ui.eclipse.eventmanager.views.helpers.EventTemplateLabelProvider;
-import org.netxms.ui.eclipse.jobs.ConsoleJob;
-import org.netxms.ui.eclipse.shared.ConsoleSharedData;
-import org.netxms.ui.eclipse.tools.MessageDialogHelper;
-import org.netxms.ui.eclipse.tools.WidgetHelper;
-import org.netxms.ui.eclipse.widgets.FilterText;
-import org.netxms.ui.eclipse.widgets.SortableTableViewer;
+import org.netxms.ui.eclipse.eventmanager.widgets.EventObjectList;
 
 /**
  * Event configuration view
  * 
  */
-public class EventConfigurator extends ViewPart implements SessionListener
+public class EventConfigurator extends ViewPart
 {
        public static final String ID = "org.netxms.ui.eclipse.eventmanager.view.event_configurator"; //$NON-NLS-1$
        public static final String JOB_FAMILY = "EventConfiguratorJob"; //$NON-NLS-1$
-
-       private static final String TABLE_CONFIG_PREFIX = "EventTemplateList"; //$NON-NLS-1$
        
-       // Columns
-       public static final int COLUMN_CODE = 0;
-       public static final int COLUMN_NAME = 1;
-       public static final int COLUMN_SEVERITY = 2;
-       public static final int COLUMN_FLAGS = 3;
-       public static final int COLUMN_MESSAGE = 4;
-       public static final int COLUMN_DESCRIPTION = 5;
-
-       private HashMap<Long, EventTemplate> eventTemplates;
-       private SortableTableViewer viewer;
-   private FilterText filterControl;
-       private Action actionNew;
-       private Action actionEdit;
-       private Action actionDelete;
-   private Action actionShowFilter;
-       private Action actionRefresh;
-       private NXCSession session;
-       private EventTemplateFilter filter;
-       private boolean filterEnabled;
-
-       /* (non-Javadoc)
-        * @see org.eclipse.ui.part.ViewPart#init(org.eclipse.ui.IViewSite)
-        */
-       @Override
-   public void init(IViewSite site) throws PartInitException
-   {
-      super.init(site);
+   private static final String TABLE_CONFIG_PREFIX = "EventTemplateList"; //$NON-NLS-1$
 
-      IDialogSettings settings = Activator.getDefault().getDialogSettings();
-      filterEnabled = settings.getBoolean("EventConfigurator.filterEnabled"); //$NON-NLS-1$
-   }
+       private EventObjectList dataView;
 
    /* (non-Javadoc)
         * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
         */
        @Override
        public void createPartControl(Composite parent)
-       {
-               session = (NXCSession)ConsoleSharedData.getSession();
-               
+       {               
       parent.setLayout(new FormLayout());
       
-      // Create filter area
-      filterControl = new FilterText(parent, SWT.NONE);
-      filterControl.addModifyListener(new ModifyListener() {
-         @Override
-         public void modifyText(ModifyEvent e)
-         {
-            onFilterModify();
-         }
-      });
-      filterControl.setCloseAction(new Action() {
-         @Override
-         public void run()
-         {
-            enableFilter(false);
-         }
-      });
-               
-               final String[] names = { Messages.get().EventConfigurator_ColCode, Messages.get().EventConfigurator_ColName, Messages.get().EventConfigurator_ColSeverity, Messages.get().EventConfigurator_ColFlags, Messages.get().EventConfigurator_ColMessage, Messages.get().EventConfigurator_ColDescription };
-               final int[] widths = { 70, 200, 90, 50, 400, 400 };
-               viewer = new SortableTableViewer(parent, names, widths, 0, SWT.UP, SortableTableViewer.DEFAULT_STYLE);
-               WidgetHelper.restoreTableViewerSettings(viewer, Activator.getDefault().getDialogSettings(), TABLE_CONFIG_PREFIX);
-               viewer.setContentProvider(new ArrayContentProvider());
-               viewer.setLabelProvider(new EventTemplateLabelProvider());
-               viewer.setComparator(new EventTemplateComparator());
-               filter = new EventTemplateFilter();
-               viewer.addFilter(filter);
-               viewer.addSelectionChangedListener(new ISelectionChangedListener()
-               {
-                       @Override
-                       public void selectionChanged(SelectionChangedEvent event)
-                       {
-                               IStructuredSelection selection = (IStructuredSelection)event.getSelection();
-                               if (selection != null)
-                               {
-                                       actionEdit.setEnabled(selection.size() == 1);
-                                       actionDelete.setEnabled(selection.size() > 0);
-                               }
-                       }
-               });
-               viewer.addDoubleClickListener(new IDoubleClickListener() {
-                       @Override
-                       public void doubleClick(DoubleClickEvent event)
-                       {
-                               actionEdit.run();
-                       }
-               });
-               viewer.getTable().addDisposeListener(new DisposeListener() {
-                       @Override
-                       public void widgetDisposed(DisposeEvent e)
-                       {
-                               WidgetHelper.saveTableViewerSettings(viewer, Activator.getDefault().getDialogSettings(), TABLE_CONFIG_PREFIX);
-                       }
-               });
-               
-      // Setup layout
+      dataView = new EventObjectList(this, parent, SWT.NONE, TABLE_CONFIG_PREFIX);
       FormData fd = new FormData();
       fd.left = new FormAttachment(0, 0);
-      fd.top = new FormAttachment(filterControl);
+      fd.top = new FormAttachment(100, 0);
       fd.right = new FormAttachment(100, 0);
       fd.bottom = new FormAttachment(100, 0);
-      viewer.getControl().setLayoutData(fd);
+      dataView.setLayoutData(fd);
       
-      fd = new FormData();
-      fd.left = new FormAttachment(0, 0);
-      fd.top = new FormAttachment(0, 0);
-      fd.right = new FormAttachment(100, 0);
-      filterControl.setLayoutData(fd);
-               
-      activateContext();
-               createActions();
-               contributeToActionBars();
-               createPopupMenu();
-
-               refreshView();
-               session.addListener(this);
-
-      // Set initial focus to filter input line
-      if (filterEnabled)
-         filterControl.setFocus();
-      else
-         enableFilter(false); // Will hide filter area correctly
-       }
-
-       /**
-        * Refresh view
-        */
-       private void refreshView()
-       {
-               new ConsoleJob(Messages.get().EventConfigurator_OpenJob_Title, this, Activator.PLUGIN_ID, JOB_FAMILY) {
+               dataView.getViewer().addDoubleClickListener(new IDoubleClickListener() {
                        @Override
-                       protected String getErrorMessage()
-                       {
-                               return Messages.get().EventConfigurator_OpenJob_Error;
-                       }
-
-                       @Override
-                       protected void runInternal(IProgressMonitor monitor) throws Exception
+                       public void doubleClick(DoubleClickEvent event)
                        {
-                               final List<EventTemplate> list = session.getEventTemplates();
-                               runInUIThread(new Runnable() {
-                                       @Override
-                                       public void run()
-                                       {
-                                               eventTemplates = new HashMap<Long, EventTemplate>(list.size());
-                                               for(final EventTemplate t: list)
-                                               {
-                                                       eventTemplates.put(t.getCode(), t);
-                                               }
-                                               viewer.setInput(eventTemplates.values().toArray());
-                                       }
-                               });
+                          dataView.getActionEdit().run();
                        }
-               }.start();
-       }
-
-       /**
-        * Process client session notifications
-        */
-       @Override
-       public void notificationHandler(final SessionNotification n)
-       {
-               switch(n.getCode())
-               {
-                       case SessionNotification.EVENT_TEMPLATE_MODIFIED:
-                               viewer.getControl().getDisplay().asyncExec(new Runnable() {
-                                       @Override
-                                       public void run()
-                                       {
-                                               EventTemplate oldTmpl = eventTemplates.get(n.getSubCode());
-                                               if (oldTmpl != null)
-                                               {
-                                                       oldTmpl.setAll((EventTemplate)n.getObject());
-                                                       viewer.update(oldTmpl, null);
-                                               }
-                                               else
-                                               {
-                                                       eventTemplates.put(n.getSubCode(), (EventTemplate)n.getObject());
-                                                       viewer.setInput(eventTemplates.values().toArray());
-                                               }
-                                       }
-                               });
-                               break;
-                       case SessionNotification.EVENT_TEMPLATE_DELETED:
-                               viewer.getControl().getDisplay().asyncExec(new Runnable() {
-                                       @Override
-                                       public void run()
-                                       {
-                                               eventTemplates.remove(n.getSubCode());
-                                               viewer.setInput(eventTemplates.values().toArray());
-                                       }
-                               });
-                               break;
-               }
+               });
+               
+               contributeToActionBars();
        }
 
-   /**
-    * Activate context
-    */
-   private void activateContext()
-   {
-      IContextService contextService = (IContextService)getSite().getService(IContextService.class);
-      if (contextService != null)
-      {
-         contextService.activateContext("org.netxms.ui.eclipse.eventmanager.contexts.EventConfigurator"); //$NON-NLS-1$
-      }
-   }
-
        /**
         * Contribute actions to action bar
         */
@@ -314,11 +92,12 @@ public class EventConfigurator extends ViewPart implements SessionListener
         */
        private void fillLocalPullDown(IMenuManager manager)
        {
-               manager.add(actionNew);
+               manager.add(dataView.getActionNewTemplate());
                manager.add(new Separator());
-      manager.add(actionShowFilter);
+      manager.add(dataView.getActionShowFilter());
       manager.add(new Separator());
-               manager.add(actionRefresh);
+      manager.add(dataView.getActionShowGroups());
+               manager.add(dataView.getActionRefresh());
        }
 
        /**
@@ -329,89 +108,10 @@ public class EventConfigurator extends ViewPart implements SessionListener
         */
        private void fillLocalToolBar(IToolBarManager manager)
        {
-               manager.add(actionNew);
-      manager.add(actionShowFilter);
+               manager.add(dataView.getActionNewTemplate());
+      manager.add(dataView.getActionShowFilter());
                manager.add(new Separator());
-               manager.add(actionRefresh);
-       }
-
-       /**
-        * Create actions
-        */
-       private void createActions()
-       {
-      final IHandlerService handlerService = (IHandlerService)getSite().getService(IHandlerService.class);
-      
-               actionRefresh = new RefreshAction(this) {
-                       @Override
-                       public void run()
-                       {
-                               refreshView();
-                       }
-               };
-
-               actionNew = new Action(Messages.get().EventConfigurator_NewEvent, SharedIcons.ADD_OBJECT) {
-                       @Override
-                       public void run()
-                       {
-                               createNewEventTemplate();
-                       }
-               };
-               actionNew.setActionDefinitionId("org.netxms.ui.eclipse.eventmanager.commands.new_event_template"); //$NON-NLS-1$
-      handlerService.activateHandler(actionNew.getActionDefinitionId(), new ActionHandler(actionNew));
-
-               actionEdit = new Action(Messages.get().EventConfigurator_Properties, SharedIcons.EDIT) { //$NON-NLS-1$
-                       @Override
-                       public void run()
-                       {
-                               editEventTemplate();
-                       }
-               };
-               actionEdit.setEnabled(false);
-
-               actionDelete = new Action(Messages.get().EventConfigurator_Delete, SharedIcons.DELETE_OBJECT) {
-                       @Override
-                       public void run()
-                       {
-                               deleteEventTemplate();
-                       }
-               };
-               actionDelete.setEnabled(false);
-
-      actionShowFilter = new Action(Messages.get().EventConfigurator_ShowFilter, Action.AS_CHECK_BOX) {
-         @Override
-         public void run()
-         {
-            enableFilter(actionShowFilter.isChecked());
-         }
-      };
-      actionShowFilter.setImageDescriptor(SharedIcons.FILTER);
-      actionShowFilter.setChecked(filterEnabled);
-      actionShowFilter.setActionDefinitionId("org.netxms.ui.eclipse.eventmanager.commands.show_filter"); //$NON-NLS-1$
-      handlerService.activateHandler(actionShowFilter.getActionDefinitionId(), new ActionHandler(actionShowFilter));
-       }
-
-       /**
-        * Create pop-up menu
-        */
-       private void createPopupMenu()
-       {
-               // Create menu manager.
-               MenuManager menuMgr = new MenuManager();
-               menuMgr.setRemoveAllWhenShown(true);
-               menuMgr.addMenuListener(new IMenuListener() {
-                       public void menuAboutToShow(IMenuManager mgr)
-                       {
-                               fillContextMenu(mgr);
-                       }
-               });
-
-               // Create menu.
-               Menu menu = menuMgr.createContextMenu(viewer.getControl());
-               viewer.getControl().setMenu(menu);
-
-               // Register menu for extension.
-               getSite().registerContextMenu(menuMgr, viewer);
+               manager.add(dataView.getActionRefresh());
        }
 
        /**
@@ -422,10 +122,13 @@ public class EventConfigurator extends ViewPart implements SessionListener
        protected void fillContextMenu(final IMenuManager mgr)
        {
                mgr.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
-               mgr.add(actionNew);
-               mgr.add(actionDelete);
+               mgr.add(dataView.getActionRefresh());
+               mgr.add(dataView.getActionDelete());
+      mgr.add(dataView.getActionNewGroup());
+               mgr.add(dataView.getActionRemoveFromGroup());
                mgr.add(new Separator());
-               mgr.add(actionEdit);
+               mgr.add(dataView.getActionShowGroups());
+               mgr.add(dataView.getActionEdit());
        }
 
        /* (non-Javadoc)
@@ -434,160 +137,6 @@ public class EventConfigurator extends ViewPart implements SessionListener
        @Override
        public void setFocus()
        {
-               viewer.getControl().setFocus();
-       }
-
-       /**
-        * Create new event template
-        */
-       protected void createNewEventTemplate()
-       {
-               final EventTemplate etmpl = new EventTemplate(0);
-               EditEventTemplateDialog dlg = new EditEventTemplateDialog(getSite().getShell(), etmpl, false);
-               if (dlg.open() == Window.OK)
-               {
-                       new ConsoleJob(Messages.get().EventConfigurator_CreateJob_Title, this, Activator.PLUGIN_ID, JOB_FAMILY) {
-                               @Override
-                               protected String getErrorMessage()
-                               {
-                                       return Messages.get().EventConfigurator_CreateJob_Error;
-                               }
-       
-                               @Override
-                               protected void runInternal(IProgressMonitor monitor) throws Exception
-                               {
-                                       long code = session.generateEventCode();
-                                       etmpl.setCode(code);
-                                       session.modifyEventTemplate(etmpl);
-                                       runInUIThread(new Runnable() {
-                                               @Override
-                                               public void run()
-                                               {
-                                                       eventTemplates.put(etmpl.getCode(), etmpl);
-                                                       viewer.setInput(eventTemplates.values().toArray());
-                                                       viewer.setSelection(new StructuredSelection(etmpl), true);
-                                               }
-                                       });
-                               }
-                       }.start();
-               }
-       }
-
-       /**
-        * Edit currently selected event template
-        */
-       protected void editEventTemplate()
-       {
-               final IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
-               if (selection.size() != 1)
-                       return;
-               
-               final EventTemplate etmpl = new EventTemplate((EventTemplate)selection.getFirstElement());
-               EditEventTemplateDialog dlg = new EditEventTemplateDialog(getSite().getShell(), etmpl, false);
-               if (dlg.open() == Window.OK)
-               {
-                       new ConsoleJob(Messages.get().EventConfigurator_UpdateJob_Title, this, Activator.PLUGIN_ID, JOB_FAMILY) {
-                               @Override
-                               protected String getErrorMessage()
-                               {
-                                       return Messages.get().EventConfigurator_UpdateJob_Error;
-                               }
-
-                               @Override
-                               protected void runInternal(IProgressMonitor monitor) throws Exception
-                               {
-                                       session.modifyEventTemplate(etmpl);
-                                       runInUIThread(new Runnable() {
-                                               @Override
-                                               public void run()
-                                               {
-                                                       eventTemplates.put(etmpl.getCode(), etmpl);
-                                                       viewer.setInput(eventTemplates.values());
-                                                       viewer.setSelection(new StructuredSelection(etmpl));
-                                               }
-                                       });
-                               }
-                       }.start();
-               }
-       }
-
-       /**
-        * Delete selected event templates
-        */
-       protected void deleteEventTemplate()
-       {
-               final IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
-
-               final String message = ((selection.size() > 1) ? Messages.get().EventConfigurator_DeleteConfirmation_Plural : Messages.get().EventConfigurator_DeleteConfirmation_Singular);
-               final Shell shell = getViewSite().getShell();
-               if (!MessageDialogHelper.openQuestion(shell, Messages.get().EventConfigurator_DeleteConfirmationTitle, message))
-               {
-                       return;
-               }
-               
-               new ConsoleJob(Messages.get().EventConfigurator_DeleteJob_Title, this, Activator.PLUGIN_ID, JOB_FAMILY) {
-                       @Override
-                       protected String getErrorMessage()
-                       {
-                               return Messages.get().EventConfigurator_DeleteJob_Error;
-                       }
-
-                       @SuppressWarnings("unchecked")
-                       @Override
-                       protected void runInternal(IProgressMonitor monitor) throws Exception
-                       {
-                               Iterator<EventTemplate> it = selection.iterator();
-                               while(it.hasNext())
-                               {
-                                       session.deleteEventTemplate(it.next().getCode());
-                               }
-                       }
-               }.start();
-       }
-
-   /**
-    * Enable or disable filter
-    * 
-    * @param enable New filter state
-    */
-   private void enableFilter(boolean enable)
-   {
-      filterEnabled = enable;
-      filterControl.setVisible(filterEnabled);
-      FormData fd = (FormData)viewer.getControl().getLayoutData();
-      fd.top = enable ? new FormAttachment(filterControl) : new FormAttachment(0, 0);
-      viewer.getControl().getParent().layout();
-      if (enable)
-      {
-         filterControl.setFocus();
-      }
-      else
-      {
-         filterControl.setText(""); //$NON-NLS-1$
-         onFilterModify();
-      }
-      actionShowFilter.setChecked(enable);
-   }
-       
-   /**
-    * Handler for filter modification
-    */
-   private void onFilterModify()
-   {
-      filter.setFilterText(filterControl.getText());
-      viewer.refresh();
-   }
-   
-       /* (non-Javadoc)
-        * @see org.eclipse.ui.part.WorkbenchPart#dispose()
-        */
-       @Override
-       public void dispose()
-       {
-      IDialogSettings settings = Activator.getDefault().getDialogSettings();
-      settings.put("EventConfigurator.filterEnabled", filterEnabled); //$NON-NLS-1$
-      
-               session.removeListener(this);
-               super.dispose();
+               dataView.getViewer().getControl().setFocus();
        }
 }
diff --git a/src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/views/helpers/EventObjectComparator.java b/src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/views/helpers/EventObjectComparator.java
new file mode 100644 (file)
index 0000000..dd92d79
--- /dev/null
@@ -0,0 +1,87 @@
+/**
+ * NetXMS - open source network management system
+ * Copyright (C) 2003-2015 Victor Kirhenshtein
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.netxms.ui.eclipse.eventmanager.views.helpers;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.swt.SWT;
+import org.netxms.client.events.EventGroup;
+import org.netxms.client.events.EventObject;
+import org.netxms.client.events.EventTemplate;
+import org.netxms.ui.eclipse.eventmanager.widgets.EventObjectList;
+import org.netxms.ui.eclipse.widgets.SortableTreeViewer;
+
+/**
+ * Event template comparator
+ */
+public class EventObjectComparator extends ViewerComparator
+{
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+        */
+       @Override
+       public int compare(Viewer viewer, Object e1, Object e2)
+       {
+               int result;
+
+               switch((Integer)((SortableTreeViewer)viewer).getTree().getSortColumn().getData("ID")) //$NON-NLS-1$
+               {
+                       case EventObjectList.COLUMN_CODE:
+                          if ((e1 instanceof EventGroup) == (e2 instanceof EventGroup))
+                   result = (int)(((EventObject)e1).getCode() - ((EventObject)e2).getCode());
+                          else
+                             result = (e1 instanceof EventGroup) ? -1 : 1;
+                               break;
+                       case EventObjectList.COLUMN_NAME:
+            if ((e1 instanceof EventGroup) == (e2 instanceof EventGroup))
+               result = ((EventObject)e1).getName().compareToIgnoreCase(((EventObject)e2).getName());
+            else
+               result = (e1 instanceof EventGroup) ? -1 : 1;
+                               break;
+                       case EventObjectList.COLUMN_SEVERITY:
+                          if (e1 instanceof EventTemplate && e2 instanceof EventTemplate)
+                             result = ((EventTemplate)e1).getSeverity().compareTo(((EventTemplate)e2).getSeverity());
+                          else
+                             result = 0;
+                               break;
+                       case EventObjectList.COLUMN_FLAGS:
+            if (e1 instanceof EventTemplate && e2 instanceof EventTemplate)
+               result = ((EventTemplate)e1).getFlags() - ((EventTemplate)e2).getFlags();
+            else
+               result = 0;
+                               break;
+                       case EventObjectList.COLUMN_MESSAGE:
+            if (e1 instanceof EventTemplate && e2 instanceof EventTemplate)
+               result = ((EventTemplate)e1).getMessage().compareToIgnoreCase(((EventTemplate)e2).getMessage());
+            else
+               result = 0;
+                               break;
+                       case EventObjectList.COLUMN_DESCRIPTION:
+            if ((e1 instanceof EventGroup) == (e2 instanceof EventGroup))
+               result = ((EventObject)e1).getDescription().compareToIgnoreCase(((EventObject)e2).getDescription());
+            else
+               result = (e1 instanceof EventGroup) ? -1 : 1;
+                               break;
+                       default:
+                               result = 0;
+                               break;
+               }
+               return (((SortableTreeViewer)viewer).getTree().getSortDirection() == SWT.UP) ? result : -result;
+       }
+}
diff --git a/src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/views/helpers/EventObjectContentProvider.java b/src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/views/helpers/EventObjectContentProvider.java
new file mode 100644 (file)
index 0000000..2dd74e8
--- /dev/null
@@ -0,0 +1,123 @@
+/**
+ * NetXMS - open source network management system
+ * Copyright (C) 2003-2017 Raden Solutions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.netxms.ui.eclipse.eventmanager.views.helpers;
+
+import java.util.List;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.netxms.client.NXCSession;
+import org.netxms.client.events.EventGroup;
+import org.netxms.client.events.EventObject;
+import org.netxms.ui.eclipse.shared.ConsoleSharedData;
+
+/**
+ * Content provider for Event Configuration Manager
+ */
+public class EventObjectContentProvider implements ITreeContentProvider
+{
+   private Viewer viewer;
+   private NXCSession session = ConsoleSharedData.getSession();
+
+   /* (non-Javadoc)
+    * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+    */
+   @Override
+   public void dispose()
+   {
+   }
+
+   /* (non-Javadoc)
+    * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+    */
+   @Override
+   public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
+   {
+      this.setViewer(viewer);
+   }
+
+   /* (non-Javadoc)
+    * @see org.eclipse.jface.viewers.ITreeContentProvider#getElements(java.lang.Object)
+    */
+   @Override
+   public Object[] getElements(Object inputElement)
+   {
+      return (Object[])inputElement;
+   }
+
+   /* (non-Javadoc)
+    * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
+    */
+   @Override
+   public Object[] getChildren(Object parentElement)
+   {
+      if ((parentElement instanceof EventGroup) && (((EventGroup)parentElement).hasChildren()))
+      {
+         List<EventObject> children = session.findMultipleEventObjects(((EventGroup)parentElement).getEventCodes());
+         Object[] childArray = new Object[children.size()];
+         for(int i = 0; i < children.size(); i++)
+         {
+            children.get(i).addParent((EventGroup)parentElement);
+            childArray[i] = children.get(i);
+         }
+         return childArray;
+      }
+      return new Object[0];
+   }
+
+   /* (non-Javadoc)
+    * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
+    */
+   @Override
+   public Object getParent(Object element)
+   {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
+    */
+   @Override
+   public boolean hasChildren(Object element)
+   {
+      if (element instanceof EventGroup)
+         return ((EventGroup)element).hasChildren();
+      
+      return false;
+   }
+
+   /**
+    * Get current viewer
+    * 
+    * @return viewer
+    */
+   public Viewer getViewer()
+   {
+      return viewer;
+   }
+
+   /**
+    * Set viewer
+    * @param viewer to set
+    */
+   public void setViewer(Viewer viewer)
+   {
+      this.viewer = viewer;
+   }
+   
+}
\ No newline at end of file
diff --git a/src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/views/helpers/EventObjectFilter.java b/src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/views/helpers/EventObjectFilter.java
new file mode 100644 (file)
index 0000000..7b330b5
--- /dev/null
@@ -0,0 +1,171 @@
+/**
+ * NetXMS - open source network management system
+ * Copyright (C) 2003-2015 Victor Kirhenshtein
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.netxms.ui.eclipse.eventmanager.views.helpers;
+
+import java.util.List;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.netxms.client.events.EventGroup;
+import org.netxms.client.events.EventObject;
+import org.netxms.client.events.EventTemplate;
+import org.netxms.ui.eclipse.shared.ConsoleSharedData;
+
+/**
+ * Event template filter
+ */
+public class EventObjectFilter extends ViewerFilter
+{
+   private String filterText = null;
+   
+   /* (non-Javadoc)
+    * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+    */
+   @Override
+   public boolean select(Viewer viewer, Object parentElement, Object element)
+   {
+      if (filterText == null)
+         return true;
+      else if (checkName(element))
+         return true;
+      else if (checkDescription(element))
+         return true;
+      else if (checkMessage(element))
+         return true;
+      
+      return false;
+   }
+   
+   /**
+    * Check template message
+    * 
+    * @param element to check
+    * @return true if succesfull
+    */
+   public boolean checkMessage(Object element)
+   {
+      if (element instanceof EventTemplate)
+         return ((EventTemplate)element).getMessage().toLowerCase().contains(filterText.toLowerCase());
+      return false;
+   }
+   
+   /**
+    * Check object description
+    * 
+    * @param element to check
+    * @return true if successful
+    */
+   public boolean checkDescription(Object element)
+   {
+      boolean result = ((EventObject)element).getDescription().toLowerCase().contains(filterText.toLowerCase());
+      if (element instanceof EventGroup)
+      {
+         List<EventObject> children = ConsoleSharedData.getSession().findMultipleEventObjects(((EventGroup)element).getEventCodes());
+         result = containsDescription(children);
+      }
+      return result;
+   }
+   
+   /**
+    * Check children for match
+    * 
+    * @param children to check
+    * @return true if succesfull
+    */
+   private boolean containsDescription(List<EventObject> children)
+   {
+      if (children != null)
+      {
+         for(EventObject f : children)
+         {
+            if (f.getDescription().toLowerCase().contains(filterText.toLowerCase()))
+               return true;
+         }
+         
+         for(EventObject f : children)
+         {
+            if (f instanceof EventGroup)
+            {
+               List<EventObject> childs = ConsoleSharedData.getSession().findMultipleEventObjects(((EventGroup)f).getEventCodes());
+               if (containsName(childs))
+                  return true;
+            }
+         }
+      }
+      return false;
+   }
+   
+   /**
+    * Check Object name
+    * 
+    * @param element to check
+    * @return true if success
+    */
+   public boolean checkName(Object element)
+   {
+      boolean result = ((EventObject)element).getName().toLowerCase().contains(filterText.toLowerCase());
+      if (element instanceof EventGroup)
+      {
+         List<EventObject> children = ConsoleSharedData.getSession().findMultipleEventObjects(((EventGroup)element).getEventCodes());
+         result = containsName(children);
+      }
+      return result;
+   }
+
+   /**
+    * Check children for match
+    * 
+    * @param children to check
+    * @return true if succesfull
+    */
+   private boolean containsName(List<EventObject> children)
+   {
+      if (children != null)
+      {
+         for(EventObject f : children)
+         {
+            if (f.getName().toLowerCase().contains(filterText.toLowerCase()))
+               return true;
+         }
+         
+         for(EventObject f : children)
+         {
+            if (f instanceof EventGroup)
+            {
+               List<EventObject> childs = ConsoleSharedData.getSession().findMultipleEventObjects(((EventGroup)f).getEventCodes());
+               if (containsName(childs))
+                  return true;
+            }
+         }
+      }
+      return false;
+   }
+   
+   /**
+    * Set filter text
+    * 
+    * @param filterText string to filter
+    */
+   public void setFilterText(String filterText)
+   {
+      if ((filterText == null) || filterText.trim().isEmpty())
+         this.filterText = null;
+      else
+         this.filterText = filterText.trim().toLowerCase();
+   }
+}
diff --git a/src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/views/helpers/EventObjectLabelProvider.java b/src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/views/helpers/EventObjectLabelProvider.java
new file mode 100644 (file)
index 0000000..c806ad3
--- /dev/null
@@ -0,0 +1,106 @@
+/**
+ * NetXMS - open source network management system
+ * Copyright (C) 2003-2013 Victor Kirhenshtein
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.netxms.ui.eclipse.eventmanager.views.helpers;
+
+import org.eclipse.jface.viewers.ITableColorProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.model.WorkbenchLabelProvider;
+import org.netxms.client.events.EventGroup;
+import org.netxms.client.events.EventObject;
+import org.netxms.client.events.EventTemplate;
+import org.netxms.ui.eclipse.console.resources.SharedIcons;
+import org.netxms.ui.eclipse.console.resources.StatusDisplayInfo;
+import org.netxms.ui.eclipse.eventmanager.widgets.EventObjectList;
+
+/**
+ * Label provider for event template objects
+ */
+public class EventObjectLabelProvider extends WorkbenchLabelProvider implements ITableLabelProvider, ITableColorProvider
+{
+   private static final Color COLOR_GROUP = new Color(Display.getDefault(), new RGB(255, 221, 173));
+   private static final Color COLOR_GROUP_CHILDREN = new Color(Display.getDefault(), new RGB(255, 255, 173));
+   
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int)
+        */
+       @Override
+       public Image getColumnImage(Object element, int columnIndex)
+       {
+          if ((columnIndex != 0))
+             return null;
+          if (element instanceof EventGroup)
+             return SharedIcons.IMG_CONTAINER;
+               return getImage(element);
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int)
+        */
+       @Override
+       public String getColumnText(Object element, int columnIndex)
+       {
+               switch(columnIndex)
+               {
+                       case EventObjectList.COLUMN_CODE:
+                          if (element instanceof EventGroup)
+                             return null;
+                               return Long.toString(((EventObject)element).getCode());
+                       case EventObjectList.COLUMN_NAME:
+                                  return ((EventObject)element).getName();
+                       case EventObjectList.COLUMN_SEVERITY:
+            if (element instanceof EventTemplate)
+               return StatusDisplayInfo.getStatusText(((EventTemplate)element).getSeverity());
+            else
+               return "";
+                       case EventObjectList.COLUMN_FLAGS:
+            if (element instanceof EventTemplate)
+               return ((((EventTemplate)element).getFlags() & EventTemplate.FLAG_WRITE_TO_LOG) != 0) ? "L" : "-"; //$NON-NLS-1$ //$NON-NLS-2$
+            else
+               return "";
+                       case EventObjectList.COLUMN_MESSAGE:
+            if (element instanceof EventTemplate)
+               return ((EventTemplate)element).getMessage();
+            else
+               return "";
+                       case EventObjectList.COLUMN_DESCRIPTION:
+                               return ((EventObject)element).getDescription();
+               }
+               return null;
+       }
+
+   @Override
+   public Color getForeground(Object element, int columnIndex)
+   {
+      return null;
+   }
+
+   @Override
+   public Color getBackground(Object element, int columnIndex)
+   {
+      if (element instanceof EventGroup)
+         return COLOR_GROUP;
+      if ((element instanceof EventObject) && ((EventObject)element).hasParents())
+         return COLOR_GROUP_CHILDREN;
+      return null;
+   }
+}
diff --git a/src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/views/helpers/EventTemplateFilter.java b/src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/views/helpers/EventTemplateFilter.java
deleted file mode 100644 (file)
index 6d7edcf..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * NetXMS - open source network management system
- * Copyright (C) 2003-2015 Victor Kirhenshtein
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-package org.netxms.ui.eclipse.eventmanager.views.helpers;
-
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.jface.viewers.ViewerFilter;
-import org.netxms.client.events.EventTemplate;
-
-/**
- * Event template filter
- */
-public class EventTemplateFilter extends ViewerFilter
-{
-   private String filterText = null;
-   
-   /* (non-Javadoc)
-    * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
-    */
-   @Override
-   public boolean select(Viewer viewer, Object parentElement, Object element)
-   {
-      if (filterText == null)
-         return true;
-      
-      return ((EventTemplate)element).getName().toLowerCase().contains(filterText) ||
-             ((EventTemplate)element).getMessage().toLowerCase().contains(filterText) ||
-             ((EventTemplate)element).getDescription().toLowerCase().contains(filterText);
-   }
-
-   /**
-    * @param filterText
-    */
-   public void setFilterText(String filterText)
-   {
-      if ((filterText == null) || filterText.trim().isEmpty())
-         this.filterText = null;
-      else
-         this.filterText = filterText.trim().toLowerCase();
-   }
-}
diff --git a/src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/widgets/EventObjectList.java b/src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/widgets/EventObjectList.java
new file mode 100644 (file)
index 0000000..21ec230
--- /dev/null
@@ -0,0 +1,836 @@
+/**
+ * NetXMS - open source network management system
+ * Copyright (C) 2003-2017 Raden Solutions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.netxms.ui.eclipse.eventmanager.widgets;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.GroupMarker;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.commands.ActionHandler;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.util.LocalSelectionTransfer;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TreeSelection;
+import org.eclipse.jface.viewers.ViewerDropAdapter;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DragSourceAdapter;
+import org.eclipse.swt.dnd.DragSourceEvent;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.dnd.TransferData;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.contexts.IContextService;
+import org.eclipse.ui.handlers.IHandlerService;
+import org.eclipse.ui.part.ViewPart;
+import org.netxms.client.NXCSession;
+import org.netxms.client.SessionListener;
+import org.netxms.client.SessionNotification;
+import org.netxms.client.events.EventGroup;
+import org.netxms.client.events.EventObject;
+import org.netxms.client.events.EventTemplate;
+import org.netxms.ui.eclipse.actions.RefreshAction;
+import org.netxms.ui.eclipse.console.resources.SharedIcons;
+import org.netxms.ui.eclipse.eventmanager.Activator;
+import org.netxms.ui.eclipse.eventmanager.Messages;
+import org.netxms.ui.eclipse.eventmanager.dialogs.EditEventGroupDialog;
+import org.netxms.ui.eclipse.eventmanager.dialogs.EditEventTemplateDialog;
+import org.netxms.ui.eclipse.eventmanager.views.helpers.EventObjectContentProvider;
+import org.netxms.ui.eclipse.eventmanager.views.helpers.EventObjectComparator;
+import org.netxms.ui.eclipse.eventmanager.views.helpers.EventObjectFilter;
+import org.netxms.ui.eclipse.eventmanager.views.helpers.EventObjectLabelProvider;
+import org.netxms.ui.eclipse.jobs.ConsoleJob;
+import org.netxms.ui.eclipse.shared.ConsoleSharedData;
+import org.netxms.ui.eclipse.tools.MessageDialogHelper;
+import org.netxms.ui.eclipse.tools.WidgetHelper;
+import org.netxms.ui.eclipse.widgets.FilterText;
+import org.netxms.ui.eclipse.widgets.SortableTreeViewer;
+
+/**
+ * Event object list widget
+ */
+public class EventObjectList extends Composite implements SessionListener
+{
+   public static final String JOB_FAMILY = "EventObjectListJob"; //$NON-NLS-1$
+   
+   // Columns
+   public static final int COLUMN_CODE = 0;
+   public static final int COLUMN_NAME = 1;
+   public static final int COLUMN_SEVERITY = 2;
+   public static final int COLUMN_FLAGS = 3;
+   public static final int COLUMN_MESSAGE = 4;
+   public static final int COLUMN_DESCRIPTION = 5;
+   
+   private HashMap<Long, EventObject> eventObjects;
+   private SortableTreeViewer viewer;
+   private FilterText filterControl;
+   private Action actionNew;
+   private Action actionEdit;
+   private Action actionDelete;
+   private Action actionRemove;
+   private Action actionShowFilter;
+   private Action actionRefresh;
+   private Action actionShowGroups;
+   private Action actionNewGroup;
+   private NXCSession session;
+   private EventObjectFilter filter;
+   private boolean filterEnabled;
+   private boolean showGroups;
+   private ViewPart viewPart ;
+   
+   /**
+    * Constructor for event object list with specific columns to show
+    * 
+    * @param viewPart the viewPart
+    * @param parent parent composite
+    * @param style style
+    * @param columnsToShow which columns to show
+    */
+   public EventObjectList(ViewPart viewPart, Composite parent, int style, final String configPrefix)
+   {
+      this(parent, style, configPrefix, false, true);
+      this.viewPart = viewPart;
+   }
+   
+   /**
+    * Constructor for event object list
+    * 
+    * @param viewPart the viewPart
+    * @param parent parent composite
+    * @param style style
+    */
+   public EventObjectList(Composite parent, int style, final String configPrefix, boolean isDialog, boolean groupsVisible)
+   {
+      super(parent, style);
+      
+      IDialogSettings settings = Activator.getDefault().getDialogSettings();
+      if (isDialog)
+         filterEnabled = true;
+      else
+         filterEnabled = settings.getBoolean(configPrefix + ".filterEnabled"); //$NON-NLS-1$
+      
+      if (groupsVisible)
+         showGroups = true;
+      else
+         showGroups = settings.getBoolean(configPrefix + ".showGroups");
+      
+      session = (NXCSession)ConsoleSharedData.getSession();
+      
+      parent.setLayout(new FormLayout());
+      
+      // Create filter area
+      filterControl = new FilterText(parent, SWT.NONE, null, !isDialog);
+      filterControl.addModifyListener(new ModifyListener() {
+         @Override
+         public void modifyText(ModifyEvent e)
+         {
+            onFilterModify();
+         }
+      });
+      filterControl.setCloseAction(new Action() {
+         @Override
+         public void run()
+         {
+            enableFilter(false);
+         }
+      });
+      
+      final String[] names = { Messages.get().EventConfigurator_ColCode, Messages.get().EventConfigurator_ColName, Messages.get().EventConfigurator_ColSeverity, Messages.get().EventConfigurator_ColFlags, Messages.get().EventConfigurator_ColMessage, Messages.get().EventConfigurator_ColDescription };
+      final int[] widths = { 70, 200, 90, 50, 400, 400 };
+      
+      viewer = new SortableTreeViewer(parent, isDialog ? Arrays.copyOfRange(names, 0, 2) : names,
+                                              isDialog ? Arrays.copyOfRange(widths, 0, 2) : widths,
+                                              0, SWT.UP, SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
+      
+      WidgetHelper.restoreTreeViewerSettings(viewer, Activator.getDefault().getDialogSettings(), configPrefix);
+      viewer.setContentProvider(new EventObjectContentProvider());
+      viewer.setLabelProvider(new EventObjectLabelProvider());
+      viewer.setComparator(new EventObjectComparator());
+      filter = new EventObjectFilter();
+      viewer.addFilter(filter);
+      viewer.addSelectionChangedListener(new ISelectionChangedListener()
+      {
+         @Override
+         public void selectionChanged(SelectionChangedEvent event)
+         {
+            ITreeSelection selection = (ITreeSelection)event.getSelection();
+            if (selection != null)
+            {
+               if (selection.getPaths().length > 0)
+                  actionRemove.setEnabled(selection.getPaths()[0].getParentPath().getLastSegment() != null);
+               actionEdit.setEnabled(selection.size() == 1);
+               actionDelete.setEnabled(selection.size() > 0);
+            }
+         }
+      });
+      viewer.getTree().addDisposeListener(new DisposeListener() {
+         @Override
+         public void widgetDisposed(DisposeEvent e)
+         {
+            WidgetHelper.saveTreeViewerSettings(viewer, Activator.getDefault().getDialogSettings(), configPrefix);
+
+            IDialogSettings settings = Activator.getDefault().getDialogSettings();
+            settings.put(configPrefix + ".filterEnabled", filterEnabled);
+            settings.put(configPrefix + ".showGroups", showGroups);
+         }
+      });
+      
+      enableDragSupport();
+      enableDropSupport();
+      
+      // Setup layout
+      FormData fd = new FormData();
+      fd.left = new FormAttachment(0, 0);
+      fd.top = new FormAttachment(filterControl);
+      fd.right = new FormAttachment(100, 0);
+      fd.bottom = new FormAttachment(100, 0);
+      viewer.getControl().setLayoutData(fd);
+      
+      fd = new FormData();
+      fd.left = new FormAttachment(0, 0);
+      fd.top = new FormAttachment(0, 0);
+      fd.right = new FormAttachment(100, 0);
+      filterControl.setLayoutData(fd);
+      
+      if (viewPart != null)
+         activateContext();
+      createActions();
+      createPopupMenu();
+
+      refreshView();
+      session.addListener(this);
+      
+      enableFilter(filterEnabled);
+
+      // Set initial focus to filter input line
+      if (filterEnabled)
+         filterControl.setFocus();
+   }
+   
+   /**
+    * Activate context
+    */
+   private void activateContext()
+   {
+      IContextService contextService = (IContextService)viewPart.getSite().getService(IContextService.class);
+      if (contextService != null)
+      {
+         contextService.activateContext("org.netxms.ui.eclipse.eventmanager.contexts.EventConfigurator"); //$NON-NLS-1$
+      }
+   }
+   
+   /**
+    * Refresh view
+    */
+   private void refreshView()
+   {
+      new ConsoleJob(Messages.get().EventConfigurator_OpenJob_Title, null, Activator.PLUGIN_ID, JOB_FAMILY) {
+         
+         /* (non-Javadoc)
+          * @see org.netxms.ui.eclipse.jobs.ConsoleJob#getErrorMessage()
+          */
+         @Override
+         protected String getErrorMessage()
+         {
+            return Messages.get().EventConfigurator_OpenJob_Error;
+         }
+
+         /* (non-Javadoc)
+          * @see org.netxms.ui.eclipse.jobs.ConsoleJob#runInternal(org.eclipse.core.runtime.IProgressMonitor)
+          */
+         @Override
+         protected void runInternal(IProgressMonitor monitor) throws Exception
+         {
+            final List<EventObject> list = session.getEventObjects();
+            runInUIThread(new Runnable() {
+               
+               /* (non-Javadoc)
+                * @see java.lang.Runnable#run()
+                */
+               @Override
+               public void run()
+               {
+                  eventObjects = new HashMap<Long, EventObject>(list.size());
+                  for(final EventObject o: list)
+                  {
+                     if ((o instanceof EventGroup) && !showGroups)
+                        continue;
+                     
+                     eventObjects.put(o.getCode(), o);
+                  }
+                  viewer.setInput(eventObjects.values().toArray());
+               }
+            });
+         }
+      }.start();
+   }
+   
+   /**
+    * Enable drag support in object tree
+    */
+   public void enableDragSupport()
+   {
+      Transfer[] transfers = new Transfer[] { LocalSelectionTransfer.getTransfer() };
+      viewer.addDragSupport(DND.DROP_COPY | DND.DROP_MOVE, transfers, new DragSourceAdapter() {
+         @Override
+         public void dragStart(DragSourceEvent event)
+         {
+            LocalSelectionTransfer.getTransfer().setSelection(viewer.getSelection());
+            event.doit = true;
+         }
+         
+         @Override
+         public void dragSetData(DragSourceEvent event)
+         {
+            event.data = LocalSelectionTransfer.getTransfer().getSelection();
+         }
+      });
+   }
+   
+   /**
+    * Enable drop support
+    */
+   public void enableDropSupport()
+   {
+      final Transfer[] transfers = new Transfer[] { LocalSelectionTransfer.getTransfer() };
+      viewer.addDropSupport(DND.DROP_COPY | DND.DROP_MOVE, transfers, new ViewerDropAdapter(viewer) {
+
+         @Override
+         public boolean performDrop(Object data)
+         {
+            TreeSelection selection = (TreeSelection)data;
+            List<?> movableSelection = selection.toList();
+            for(int i = 0; i < movableSelection.size(); i++)
+            {
+               if (((EventObject)movableSelection.get(i)).getCode() != ((EventGroup)getCurrentTarget()).getCode())
+                  ((EventGroup)getCurrentTarget()).addChild(((EventObject)movableSelection.get(i)).getCode());               
+            }            
+            modifyEventObject((EventGroup)getCurrentTarget(), false);
+            
+            return true;
+         }
+
+         @Override
+         public boolean validateDrop(Object target, int operation, TransferData transferType)
+         {
+            if ((target == null) || !LocalSelectionTransfer.getTransfer().isSupportedType(transferType))
+               return false;
+
+            IStructuredSelection selection = (IStructuredSelection)LocalSelectionTransfer.getTransfer().getSelection();
+            if (selection.isEmpty())
+               return false;
+
+            if (!(target instanceof EventGroup))
+               return false;
+
+            return true;
+         }
+         
+      });
+   }
+   
+   /* (non-Javadoc)
+    * @see org.netxms.client.SessionListener#notificationHandler(org.netxms.client.SessionNotification)
+    */
+   @Override
+   public void notificationHandler(final SessionNotification n)
+   {
+      switch(n.getCode())
+      {
+         case SessionNotification.EVENT_TEMPLATE_MODIFIED:
+            viewer.getControl().getDisplay().asyncExec(new Runnable() {
+               @Override
+               public void run()
+               {
+                  EventObject oldObj = eventObjects.get(n.getSubCode());
+                  if (oldObj != null)
+                  {
+                     oldObj.setAll((EventObject)n.getObject());
+                     viewer.refresh();
+                  }
+                  else
+                  {
+                     eventObjects.put(n.getSubCode(), (EventObject)n.getObject());
+                     viewer.setInput(eventObjects.values().toArray());
+                  }
+               }
+            });
+            break;
+         case SessionNotification.EVENT_TEMPLATE_DELETED:
+            viewer.getControl().getDisplay().asyncExec(new Runnable() {
+               @Override
+               public void run()
+               {
+                  eventObjects.remove(n.getSubCode());
+                  viewer.setInput(eventObjects.values().toArray());
+               }
+            });
+            break;
+      }
+   }
+   
+   /**
+    * Create actions
+    */
+   private void createActions()
+   {
+      actionNew = new Action(Messages.get().EventConfigurator_NewEvent, SharedIcons.ADD_OBJECT) {
+         @Override
+         public void run()
+         {
+            createNewEventTemplate();
+         }
+      };
+      actionNew.setActionDefinitionId("org.netxms.ui.eclipse.eventmanager.commands.new_event_template"); //$NON-NLS-1$
+
+      actionEdit = new Action(Messages.get().EventConfigurator_Properties, SharedIcons.EDIT) { //$NON-NLS-1$
+         @Override
+         public void run()
+         {
+            editEventTemplate();
+         }
+      };
+      actionEdit.setEnabled(false);
+
+      actionDelete = new Action(Messages.get().EventConfigurator_Delete, SharedIcons.DELETE_OBJECT) {
+         @Override
+         public void run()
+         {
+            deleteEventTemplate();
+         }
+      };
+      actionDelete.setEnabled(false);
+
+      actionShowFilter = new Action(Messages.get().EventConfigurator_ShowFilter, Action.AS_CHECK_BOX) {
+         @Override
+         public void run()
+         {
+            enableFilter(actionShowFilter.isChecked());
+         }
+      };
+      
+      actionRemove = new Action("&Remove from group") {
+         @Override
+         public void run()
+         {
+            removeFromGroup();
+         }
+      };
+      
+      actionShowGroups = new Action("&Show event groups", Action.AS_CHECK_BOX) {
+         @Override
+         public void run()
+         {
+            showEventGroups();
+         }
+      };
+      actionShowGroups.setChecked(showGroups);
+      
+      actionNewGroup = new Action("&Add new event group") {
+         @Override
+         public void run()
+         {
+            createNewEventGroup();
+         }
+      };
+      
+      actionShowFilter.setImageDescriptor(SharedIcons.FILTER);
+      actionShowFilter.setChecked(filterEnabled);
+      actionShowFilter.setActionDefinitionId("org.netxms.ui.eclipse.eventmanager.commands.show_filter"); //$NON-NLS-1$
+      
+      if (viewPart != null)
+      {
+         final IHandlerService handlerService = (IHandlerService)viewPart.getSite().getService(IHandlerService.class);
+         
+         actionNew.setActionDefinitionId("org.netxms.ui.eclipse.eventmanager.commands.new_event_template"); //$NON-NLS-1$
+         handlerService.activateHandler(actionNew.getActionDefinitionId(), new ActionHandler(actionNew));
+         
+         actionShowFilter.setActionDefinitionId("org.netxms.ui.eclipse.eventmanager.commands.show_filter"); //$NON-NLS-1$
+         handlerService.activateHandler(actionShowFilter.getActionDefinitionId(), new ActionHandler(actionShowFilter));
+         
+         actionRefresh = new RefreshAction(viewPart) {
+            @Override
+            public void run()
+            {
+               refreshView();
+            }
+         };
+      }
+      else
+      {
+         actionRefresh = new RefreshAction() {
+            @Override
+            public void run()
+            {
+               refreshView();
+            }
+         };
+      }
+   }
+
+   /**
+    * Create pop-up menu
+    */
+   private void createPopupMenu()
+   {
+      // Create menu manager.
+      MenuManager menuMgr = new MenuManager();
+      menuMgr.setRemoveAllWhenShown(true);
+      menuMgr.addMenuListener(new IMenuListener() {
+         public void menuAboutToShow(IMenuManager mgr)
+         {
+            fillContextMenu(mgr);
+         }
+      });
+
+      // Create menu.
+      Menu menu = menuMgr.createContextMenu(viewer.getControl());
+      viewer.getControl().setMenu(menu);
+
+      // Register menu for extension.
+      if (viewPart != null)
+         viewPart.getSite().registerContextMenu(menuMgr, viewer);
+   }
+
+   /**
+    * Fill context menu
+    * 
+    * @param mgr Menu manager
+    */
+   protected void fillContextMenu(final IMenuManager mgr)
+   {
+      mgr.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
+      mgr.add(actionNew);
+      mgr.add(actionDelete);
+      mgr.add(actionNewGroup);
+      mgr.add(actionRemove);
+      mgr.add(new Separator());
+      mgr.add(actionShowGroups);
+      mgr.add(actionEdit);
+   }
+
+   /**
+    * Create new event template
+    */
+   protected void createNewEventTemplate()
+   {
+      final EventTemplate etmpl = new EventTemplate(0);
+      EditEventTemplateDialog dlg = new EditEventTemplateDialog(getShell().getShell(), etmpl, false);
+      if (dlg.open() == Window.OK)
+         modifyEventObject(etmpl, true);
+   }
+   
+   /**
+    * Modify event object in server
+    * 
+    * @param obj to modify
+    */
+   protected void modifyEventObject(final EventObject obj, final boolean updateParent)
+   {      
+      new ConsoleJob(Messages.get().EventConfigurator_UpdateJob_Title, null, Activator.PLUGIN_ID, JOB_FAMILY) {
+         @Override
+         protected String getErrorMessage()
+         {
+            return Messages.get().EventConfigurator_UpdateJob_Error;
+         }
+
+         @Override
+         protected void runInternal(IProgressMonitor monitor) throws Exception
+         {
+            session.modifyEventObject(obj);
+            
+            if (updateParent)
+            {
+               runInUIThread(new Runnable() {
+                  
+                  /* (non-Javadoc)
+                   * @see java.lang.Runnable#run()
+                   */
+                  @Override
+                  public void run()
+                  {
+                     ITreeSelection selection = (ITreeSelection)viewer.getSelection();
+                     if (selection.size() == 1 && selection.getFirstElement() instanceof EventGroup)
+                     {
+                        ((EventGroup)selection.getFirstElement()).addChild(obj.getCode());
+                        modifyEventObject((EventGroup)selection.getFirstElement(), false);
+                     }
+                  }
+               });
+            }
+         }
+      }.start();
+   }
+
+   /**
+    * Edit currently selected event template
+    */
+   protected void editEventTemplate()
+   {
+      final IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
+      if (selection.size() != 1)
+         return;
+      
+      if (selection.getFirstElement() instanceof EventGroup)
+      {
+         final EventGroup group = new EventGroup((EventGroup)selection.getFirstElement());
+         EditEventGroupDialog dlg = new EditEventGroupDialog(getShell().getShell(), group);
+         if (dlg.open() == Window.OK)
+            modifyEventObject(group, false);
+         else
+            return;
+      }
+      
+      final EventTemplate etmpl = new EventTemplate((EventTemplate)selection.getFirstElement());
+      EditEventTemplateDialog dlg = new EditEventTemplateDialog(getShell().getShell(), etmpl, false);
+      if (dlg.open() == Window.OK)
+         modifyEventObject(etmpl, false);
+   }
+
+   /**
+    * Delete selected event templates
+    */
+   protected void deleteEventTemplate()
+   {
+      final IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
+
+      final String message = ((selection.size() > 1) ? Messages.get().EventConfigurator_DeleteConfirmation_Plural : Messages.get().EventConfigurator_DeleteConfirmation_Singular);
+      final Shell shell = viewPart.getSite().getShell();
+      if (!MessageDialogHelper.openQuestion(shell, Messages.get().EventConfigurator_DeleteConfirmationTitle, message))
+         return;
+      
+      new ConsoleJob(Messages.get().EventConfigurator_DeleteJob_Title, null, Activator.PLUGIN_ID, JOB_FAMILY) {
+         @Override
+         protected String getErrorMessage()
+         {
+            return Messages.get().EventConfigurator_DeleteJob_Error;
+         }
+
+         @SuppressWarnings("unchecked")
+         @Override
+         protected void runInternal(IProgressMonitor monitor) throws Exception
+         {
+            Iterator<EventObject> it = selection.iterator();
+            while(it.hasNext())
+            {
+               session.deleteEventObject(it.next().getCode());
+            }
+         }
+      }.start();
+   }
+   
+   /**
+    * Remove event object from group
+    */
+   @SuppressWarnings("unchecked")
+   protected void removeFromGroup()
+   {
+      ITreeSelection selection = (ITreeSelection)viewer.getSelection();
+      List<EventObject> list = selection.toList();
+      for(int i = 0; i < selection.size(); i++)
+      {
+         EventGroup parent = (EventGroup)selection.getPathsFor(list.get(i))[0].getParentPath().getLastSegment();
+         EventObject child = list.get(i);
+         parent.removeChild(child.getCode());
+         modifyEventObject(parent, false);
+      }
+   }
+   
+   /**
+    * Create new Event group 
+    */
+   protected void createNewEventGroup()
+   {
+      EventGroup group = new EventGroup();
+         
+      EditEventGroupDialog dlg = new EditEventGroupDialog(getShell().getShell(), group);
+      if (dlg.open() == Window.OK)
+         modifyEventObject(group, true);
+   } 
+   
+   /**
+    * Enable/Disable event group viewing
+    */
+   protected void showEventGroups()
+   {
+      if (showGroups)
+         showGroups = false;
+      else
+         showGroups = true;
+      
+      actionShowGroups.setChecked(showGroups);
+      actionNewGroup.setEnabled(showGroups);
+      actionRefresh.run();
+   }
+   
+   /**
+    * Enable or disable filter
+    * 
+    * @param enable New filter state
+    */
+   private void enableFilter(boolean enable)
+   {
+      filterEnabled = enable;
+      filterControl.setVisible(filterEnabled);
+      FormData fd = (FormData)viewer.getControl().getLayoutData();
+      fd.top = enable ? new FormAttachment(filterControl) : new FormAttachment(0, 0);
+      viewer.getControl().getParent().layout();
+      if (enable)
+      {
+         filterControl.setFocus();
+      }
+      else
+      {
+         filterControl.setText(""); //$NON-NLS-1$
+         onFilterModify();
+      }
+      actionShowFilter.setChecked(enable);
+   }
+   
+   /**
+    * Handler for filter modification
+    */
+   private void onFilterModify()
+   {
+      filter.setFilterText(filterControl.getText());
+      viewer.refresh();
+   }
+   
+   /* (non-Javadoc)
+    * @see org.eclipse.ui.part.WorkbenchPart#dispose()
+    */
+   @Override
+   public void dispose()
+   {
+      IDialogSettings settings = Activator.getDefault().getDialogSettings();
+      settings.put("EventConfigurator.filterEnabled", filterEnabled); //$NON-NLS-1$
+      
+      session.removeListener(this);
+      super.dispose();
+   }
+   
+   /**
+    * Get underlying tree viewer
+    * @return viewer
+    */
+   public SortableTreeViewer getViewer()
+   {
+      return viewer;
+   }
+   
+   /**
+    * Get create new template action
+    * 
+    * @return new template action
+    */
+   public Action getActionNewTemplate()
+   {
+      return actionNew;
+   }
+   
+   /**
+    * Get edit event object action
+    * 
+    * @return edit action
+    */
+   public Action getActionEdit()
+   {
+      return actionEdit;
+   }
+   
+   /**
+    * Get delete action
+    * 
+    * @return delete action
+    */
+   public Action getActionDelete()
+   {
+      return actionDelete;
+   }
+   
+   /**
+    * Get remove from group action
+    * 
+    * @return remove from group action
+    */
+   public Action getActionRemoveFromGroup()
+   {
+      return actionRemove;
+   }
+   
+   /**
+    * Get show filter action
+    *  
+    * @return show filter action
+    */
+   public Action getActionShowFilter()
+   {
+      return actionShowFilter;
+   }
+   
+   /**
+    * Get refresh action
+    * 
+    * @return refresh action
+    */
+   public Action getActionRefresh()
+   {
+      return actionRefresh;
+   }
+   
+   /**
+    * Get show groups action
+    * 
+    * @return show groups action
+    */
+   public Action getActionShowGroups()
+   {
+      return actionShowGroups;
+   }
+   
+   /**
+    * Get create new group action
+    * 
+    * @return create new group action
+    */
+   public Action getActionNewGroup()
+   {
+      return actionNewGroup;
+   }
+}
index b57c91e..69b4137 100644 (file)
@@ -21,7 +21,9 @@ package org.netxms.ui.eclipse.eventmanager.widgets;
 import org.eclipse.jface.window.Window;
 import org.eclipse.swt.widgets.Composite;
 import org.netxms.client.NXCSession;
+import org.netxms.client.events.EventObject;
 import org.netxms.client.events.EventTemplate;
+import org.netxms.ui.eclipse.console.resources.SharedIcons;
 import org.netxms.ui.eclipse.console.resources.StatusDisplayInfo;
 import org.netxms.ui.eclipse.eventmanager.Messages;
 import org.netxms.ui.eclipse.eventmanager.dialogs.EventSelectionDialog;
@@ -62,18 +64,22 @@ public class EventSelector extends AbstractSelector
        @Override
        protected void selectionButtonHandler()
        {
-               EventSelectionDialog dlg = new EventSelectionDialog(getShell());
+               EventSelectionDialog dlg = new EventSelectionDialog(getShell(), false);
                dlg.enableMultiSelection(false);
                if (dlg.open() == Window.OK)
                {
                        long prevEventCode = eventCode;
-                       EventTemplate[] events = dlg.getSelectedEvents();
+                       EventObject[] events = dlg.getSelectedEvents();
                        if (events.length > 0)
                        {
                                eventCode = events[0].getCode();
                                setText(events[0].getName());
-                               setImage(StatusDisplayInfo.getStatusImage(events[0].getSeverity()));
-                               getTextControl().setToolTipText(generateToolTipText(events[0]));
+                               if (events[0] instanceof EventTemplate)
+                               setImage(StatusDisplayInfo.getStatusImage(((EventTemplate)events[0]).getSeverity()));
+                               else
+                                  setImage(SharedIcons.IMG_CONTAINER);
+
+            getTextControl().setToolTipText(generateToolTipText(events[0]));
                        }
                        else
                        {
@@ -125,12 +131,15 @@ public class EventSelector extends AbstractSelector
                this.eventCode = eventCode;
                if (eventCode != 0)
                {
-                       EventTemplate event = ((NXCSession)ConsoleSharedData.getSession()).findEventTemplateByCode(eventCode);
-                       if (event != null)
+                       EventObject object = ((NXCSession)ConsoleSharedData.getSession()).findEventObjectByCode(eventCode);
+                       if (object != null)
                        {
-                               setText(event.getName());
-                               setImage(StatusDisplayInfo.getStatusImage(event.getSeverity()));
-                               getTextControl().setToolTipText(generateToolTipText(event));
+                               setText(object.getName());
+                               if (object instanceof EventTemplate)
+                                  setImage(StatusDisplayInfo.getStatusImage(((EventTemplate)object).getSeverity()));
+                               else
+                                  setImage(SharedIcons.IMG_CONTAINER);
+                               getTextControl().setToolTipText(generateToolTipText(object));
                        }
                        else
                        {
@@ -153,17 +162,20 @@ public class EventSelector extends AbstractSelector
         * @param event event template
         * @return tooltip text
         */
-       private String generateToolTipText(EventTemplate event)
+       private String generateToolTipText(EventObject object)
        {
-               StringBuilder sb = new StringBuilder(event.getName());
+               StringBuilder sb = new StringBuilder(object.getName());
                sb.append(" ["); //$NON-NLS-1$
-               sb.append(event.getCode());
-               sb.append(Messages.get().EventSelector_Severity);
-               sb.append(StatusDisplayInfo.getStatusText(event.getSeverity()));
-               sb.append("\n\n"); //$NON-NLS-1$
-               sb.append(event.getMessage());
+               sb.append(object.getCode());
+               if (object instanceof EventTemplate)
+               {
+               sb.append(Messages.get().EventSelector_Severity);
+               sb.append(StatusDisplayInfo.getStatusText(((EventTemplate)object).getSeverity()));
+         sb.append("\n\n"); //$NON-NLS-1$
+         sb.append(((EventTemplate)object).getMessage());
+               }
                sb.append("\n\n"); //$NON-NLS-1$
-               sb.append(event.getDescription().replace("\r", "")); //$NON-NLS-1$ //$NON-NLS-2$
+               sb.append(object.getDescription().replace("\r", "")); //$NON-NLS-1$ //$NON-NLS-2$
                return sb.toString();
        }
 
index 452a812..2f8c0db 100644 (file)
@@ -27,7 +27,7 @@ import org.eclipse.ui.model.WorkbenchLabelProvider;
 import org.netxms.client.NXCSession;
 import org.netxms.client.TableRow;
 import org.netxms.client.events.Alarm;
-import org.netxms.client.events.EventTemplate;
+import org.netxms.client.events.EventObject;
 import org.netxms.client.log.Log;
 import org.netxms.client.log.LogColumn;
 import org.netxms.client.objects.AbstractObject;
@@ -183,8 +183,8 @@ public class LogLabelProvider implements ITableLabelProvider
                                try
                                {
                                        long code = Long.parseLong(value);
-                                       EventTemplate evt = session.findEventTemplateByCode(code);
-                                       return (evt != null) ? evt.getName() : ("[" + code + "]"); //$NON-NLS-1$ //$NON-NLS-2$
+                                       EventObject evo = session.findEventObjectByCode(code);
+                                       return (evo != null) ? evo.getName() : ("[" + code + "]"); //$NON-NLS-1$ //$NON-NLS-2$
                                }
                                catch(NumberFormatException e)
                                {
index 678033a..f470e7c 100644 (file)
@@ -33,7 +33,7 @@ import org.eclipse.ui.forms.widgets.ImageHyperlink;
 import org.eclipse.ui.model.WorkbenchLabelProvider;
 import org.netxms.client.constants.ColumnFilterType;
 import org.netxms.client.constants.Severity;
-import org.netxms.client.events.EventTemplate;
+import org.netxms.client.events.EventObject;
 import org.netxms.client.log.ColumnFilter;
 import org.netxms.ui.eclipse.console.resources.SharedIcons;
 import org.netxms.ui.eclipse.console.resources.StatusDisplayInfo;
@@ -123,11 +123,11 @@ public class EventConditionEditor extends ConditionEditor
       {
          setSelectedOperation(initialFilter.isNegated() ? 1 : 0);
          eventCode = initialFilter.getNumericValue();
-         EventTemplate e = ConsoleSharedData.getSession().findEventTemplateByCode(eventCode);
-         if (e != null)
+         EventObject o = ConsoleSharedData.getSession().findEventObjectByCode(eventCode);
+         if (o != null && o instanceof EventObject)
          {
-            objectName.setText(e.getName());
-            objectName.setImage(labelProvider.getImage(e));
+            objectName.setText(o.getName());
+            objectName.setImage(labelProvider.getImage(o));
          }
          else
          {
@@ -142,11 +142,11 @@ public class EventConditionEditor extends ConditionEditor
         */
        private void selectEvent()
        {
-               EventSelectionDialog dlg = new EventSelectionDialog(getShell());
+               EventSelectionDialog dlg = new EventSelectionDialog(getShell(), false);
                dlg.enableMultiSelection(false);
                if (dlg.open() == Window.OK)
                {
-                       EventTemplate[] events = dlg.getSelectedEvents();
+                  EventObject[] events = dlg.getSelectedEvents();
                        if (events.length > 0)
                        {
                                eventCode = events[0].getCode();
index e43c232..91ed26c 100644 (file)
@@ -29,6 +29,7 @@ import org.eclipse.ui.forms.events.HyperlinkAdapter;
 import org.eclipse.ui.forms.events.HyperlinkEvent;
 import org.eclipse.ui.forms.widgets.FormToolkit;
 import org.eclipse.ui.forms.widgets.ImageHyperlink;
+import org.netxms.client.events.EventObject;
 import org.netxms.client.events.EventTemplate;
 import org.netxms.client.reporting.ReportParameter;
 import org.netxms.ui.eclipse.console.resources.SharedIcons;
@@ -113,16 +114,17 @@ public class EventFieldEditor extends FieldEditor
         */
        private void selectEvent()
        {
-               EventSelectionDialog dlg = new EventSelectionDialog(getShell());
+               EventSelectionDialog dlg = new EventSelectionDialog(getShell(), false);
                dlg.enableMultiSelection(false);
                if (dlg.open() == Window.OK)
                {
-                  EventTemplate[] events = dlg.getSelectedEvents();
+                  EventObject[] events = dlg.getSelectedEvents();
                        if (events.length > 0)
                        {
                                eventCode = events[0].getCode();
                                text.setText(events[0].getName());
-                               text.setImage(StatusDisplayInfo.getStatusImage(events[0].getSeverity()));
+                               if (events[0] instanceof EventTemplate)
+                                  text.setImage(StatusDisplayInfo.getStatusImage(((EventTemplate)events[0]).getSeverity()));
                        }
                        else
                        {
index 43d8154..90640b5 100644 (file)
@@ -24,7 +24,7 @@ import org.eclipse.jface.viewers.ViewerComparator;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.TableColumn;
 import org.netxms.client.NXCSession;
-import org.netxms.client.events.EventTemplate;
+import org.netxms.client.events.EventObject;
 import org.netxms.client.snmp.SnmpTrap;
 import org.netxms.ui.eclipse.shared.ConsoleSharedData;
 import org.netxms.ui.eclipse.snmp.Messages;
@@ -68,10 +68,10 @@ public class SnmpTrapComparator extends ViewerComparator
                                rc = trap1.getObjectId().compareTo(trap2.getObjectId());
                                break;
                        case SnmpTrapEditor.COLUMN_EVENT:
-                               EventTemplate evt1 = session.findEventTemplateByCode(trap1.getEventCode());
-                               EventTemplate evt2 = session.findEventTemplateByCode(trap2.getEventCode());
-                               String name1 = (evt1 != null) ? evt1.getName() : Messages.get().SnmpTrapComparator_Unknown;
-                               String name2 = (evt2 != null) ? evt2.getName() : Messages.get().SnmpTrapComparator_Unknown;
+                               EventObject evo1 = session.findEventObjectByCode(trap1.getEventCode());
+                               EventObject evo2 = session.findEventObjectByCode(trap2.getEventCode());
+                               String name1 = (evo1 != null) ? evo1.getName() : Messages.get().SnmpTrapComparator_Unknown;
+                               String name2 = (evo2 != null) ? evo2.getName() : Messages.get().SnmpTrapComparator_Unknown;
                                rc = name1.compareToIgnoreCase(name2);
                                break;
                        case SnmpTrapEditor.COLUMN_DESCRIPTION:
index ad8820d..9449d6b 100644 (file)
@@ -22,7 +22,7 @@ import org.eclipse.jface.viewers.ILabelProviderListener;
 import org.eclipse.jface.viewers.ITableLabelProvider;
 import org.eclipse.swt.graphics.Image;
 import org.netxms.client.NXCSession;
-import org.netxms.client.events.EventTemplate;
+import org.netxms.client.events.EventObject;
 import org.netxms.client.snmp.SnmpTrap;
 import org.netxms.ui.eclipse.shared.ConsoleSharedData;
 import org.netxms.ui.eclipse.snmp.Messages;
@@ -67,8 +67,8 @@ public class SnmpTrapLabelProvider implements ITableLabelProvider
                        case SnmpTrapEditor.COLUMN_TRAP_OID:
                                return trap.getObjectId().toString();
                        case SnmpTrapEditor.COLUMN_EVENT:
-                               EventTemplate evt = session.findEventTemplateByCode(trap.getEventCode());
-                               return (evt != null) ? evt.getName() : Messages.get().SnmpTrapLabelProvider_Unknown;
+                               EventObject evo = session.findEventObjectByCode(trap.getEventCode());
+                               return (evo != null) ? evo.getName() : Messages.get().SnmpTrapLabelProvider_Unknown;
                        case SnmpTrapEditor.COLUMN_DESCRIPTION:
                                return trap.getDescription();
                }
index 626a5ad..ddac263 100644 (file)
@@ -24,7 +24,7 @@ import org.eclipse.jface.viewers.ViewerComparator;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.TableColumn;
 import org.netxms.client.NXCSession;
-import org.netxms.client.events.EventTemplate;
+import org.netxms.client.events.EventObject;
 import org.netxms.client.snmp.SnmpTrap;
 import org.netxms.ui.eclipse.serverconfig.dialogs.SelectSnmpTrapDialog;
 import org.netxms.ui.eclipse.shared.ConsoleSharedData;
@@ -64,10 +64,10 @@ public class SnmpTrapComparator extends ViewerComparator
                                rc = trap1.getObjectId().compareTo(trap2.getObjectId());
                                break;
                        case SelectSnmpTrapDialog.COLUMN_EVENT:
-                               EventTemplate evt1 = session.findEventTemplateByCode(trap1.getEventCode());
-                               EventTemplate evt2 = session.findEventTemplateByCode(trap2.getEventCode());
-                               String name1 = (evt1 != null) ? evt1.getName() : ("[" + Integer.toString(trap1.getEventCode()) + "]"); //$NON-NLS-1$ //$NON-NLS-2$
-                               String name2 = (evt2 != null) ? evt2.getName() : ("[" + Integer.toString(trap2.getEventCode()) + "]"); //$NON-NLS-1$ //$NON-NLS-2$
+                          EventObject evo1 = session.findEventObjectByCode(trap1.getEventCode());
+            EventObject evo2 = session.findEventObjectByCode(trap2.getEventCode());
+                               String name1 = (evo1 != null) ? evo1.getName() : ("[" + Integer.toString(trap1.getEventCode()) + "]"); //$NON-NLS-1$ //$NON-NLS-2$
+                               String name2 = (evo2 != null) ? evo2.getName() : ("[" + Integer.toString(trap2.getEventCode()) + "]"); //$NON-NLS-1$ //$NON-NLS-2$
                                rc = name1.compareToIgnoreCase(name2);
                                break;
                        case SelectSnmpTrapDialog.COLUMN_DESCRIPTION:
index 6cf1b09..5b88a8c 100644 (file)
@@ -67,7 +67,7 @@ public class SnmpTrapFilter extends ViewerFilter
    public boolean eventMatch(Object element)
    {
       NXCSession session = (NXCSession)ConsoleSharedData.getSession();
-      if(session.findEventTemplateByCode(((SnmpTrap)element).getEventCode()).toString().toLowerCase().contains(filterString))
+      if(session.findEventObjectByCode(((SnmpTrap)element).getEventCode()).toString().toLowerCase().contains(filterString))
          return true;
       return false;
    }
index 247e49d..e41d65e 100644 (file)
@@ -22,7 +22,7 @@ import org.eclipse.jface.viewers.ITableLabelProvider;
 import org.eclipse.jface.viewers.LabelProvider;
 import org.eclipse.swt.graphics.Image;
 import org.netxms.client.NXCSession;
-import org.netxms.client.events.EventTemplate;
+import org.netxms.client.events.EventObject;
 import org.netxms.client.snmp.SnmpTrap;
 import org.netxms.ui.eclipse.serverconfig.dialogs.SelectSnmpTrapDialog;
 import org.netxms.ui.eclipse.shared.ConsoleSharedData;
@@ -55,8 +55,8 @@ public class TrapListLabelProvider extends LabelProvider implements ITableLabelP
                        case SelectSnmpTrapDialog.COLUMN_OID:
                                return trap.getObjectId().toString();
                        case SelectSnmpTrapDialog.COLUMN_EVENT:
-                               EventTemplate evt = session.findEventTemplateByCode(trap.getEventCode());
-                               return (evt != null) ? evt.getName() : ("[" + Integer.toString(trap.getEventCode()) + "]"); //$NON-NLS-1$ //$NON-NLS-2$
+                               EventObject evo = session.findEventObjectByCode(trap.getEventCode());
+                               return (evo != null) ? evo.getName() : ("[" + Integer.toString(trap.getEventCode()) + "]"); //$NON-NLS-1$ //$NON-NLS-2$
                        case SelectSnmpTrapDialog.COLUMN_DESCRIPTION:
                                return trap.getDescription();
                }
index 1ba8c18..8c5530c 100644 (file)
@@ -64,6 +64,8 @@ import org.netxms.base.NXCommon;
 import org.netxms.client.NXCSession;
 import org.netxms.client.Script;
 import org.netxms.client.datacollection.DciSummaryTableDescriptor;
+import org.netxms.client.events.EventGroup;
+import org.netxms.client.events.EventObject;
 import org.netxms.client.events.EventProcessingPolicyRule;
 import org.netxms.client.events.EventTemplate;
 import org.netxms.client.market.Repository;
@@ -116,7 +118,7 @@ public class ExportFileBuilder extends ViewPart implements ISaveablePart
    private TableViewer summaryTableViewer;
        private Action actionSave;
        private Action actionPublish;
-       private Map<Long, EventTemplate> events = new HashMap<Long, EventTemplate>();
+       private Map<Long, EventObject> events = new HashMap<Long, EventObject>();
        private Map<Long, Template> templates = new HashMap<Long, Template>();
        private Map<Long, SnmpTrap> traps = new HashMap<Long, SnmpTrap>();
        private Map<UUID, EventProcessingPolicyRule> rules = new HashMap<UUID, EventProcessingPolicyRule>();
@@ -878,8 +880,8 @@ public class ExportFileBuilder extends ViewPart implements ISaveablePart
        {
       final long[] eventList = new long[events.size()];
       int i = 0;
-      for(EventTemplate t : events.values())
-         eventList[i++] = t.getCode();
+      for(EventObject o : events.values())
+         eventList[i++] = o.getCode();
       
       final long[] templateList = new long[templates.size()];
       i = 0;
@@ -1079,16 +1081,37 @@ public class ExportFileBuilder extends ViewPart implements ISaveablePart
        }
        
        /**
+        * Add event group contents to list
+        */
+       private void addEventGroups(EventGroup group)
+       {
+          List<EventObject> objects = session.findMultipleEventObjects(group.getEventCodes());
+          for(EventObject o : objects)
+          {
+             if (o instanceof EventGroup)
+                addEventGroups((EventGroup)o);
+             else
+                events.put(o.getCode(), o);
+          }
+       }
+       
+       /**
         * Add events to list
         */
        private void addEvents()
        {
-               EventSelectionDialog dlg = new EventSelectionDialog(getSite().getShell());
+               EventSelectionDialog dlg = new EventSelectionDialog(getSite().getShell(), true);
                dlg.enableMultiSelection(true);
                if (dlg.open() == Window.OK)
                {
-                       for(EventTemplate t : dlg.getSelectedEvents())
-                               events.put(t.getCode(), t);
+                       for(EventObject t : dlg.getSelectedEvents())
+                       {
+                               if (t instanceof EventGroup)
+                                  addEventGroups((EventGroup)t);
+                               else
+                   events.put(t.getCode(), t);
+                                     
+                       }
                        eventViewer.setInput(events.values().toArray());
                        setModified();
                }
@@ -1134,7 +1157,7 @@ public class ExportFileBuilder extends ViewPart implements ISaveablePart
                                                @Override
                                                public void run()
                                                {
-                                                  for(EventTemplate e : session.findMultipleEventTemplates(eventCodes.toArray(new Long[eventCodes.size()])))
+                                                  for(EventObject e : session.findMultipleEventObjects(eventCodes.toArray(new Long[eventCodes.size()])))
                                                   {
                                                      events.put(e.getCode(), e);
                                                   }
@@ -1176,9 +1199,9 @@ public class ExportFileBuilder extends ViewPart implements ISaveablePart
                        setModified();
                        if (eventCodes.size() > 0)
                        {
-                               for(EventTemplate e : session.findMultipleEventTemplates(eventCodes.toArray(new Long[eventCodes.size()])))
+                               for(EventObject o : session.findMultipleEventObjects(eventCodes.toArray(new Long[eventCodes.size()])))
                                {
-                                  events.put(e.getCode(), e);
+                                  events.put(o.getCode(), o);
                                }
                                eventViewer.setInput(events.values().toArray());
                        };
@@ -1209,9 +1232,9 @@ public class ExportFileBuilder extends ViewPart implements ISaveablePart
                        setModified();
                        if (eventCodes.size() > 0)
                        {
-                               for(EventTemplate e : session.findMultipleEventTemplates(eventCodes.toArray(new Long[eventCodes.size()])))
+                               for(EventObject o : session.findMultipleEventObjects(eventCodes.toArray(new Long[eventCodes.size()])))
                                {
-                                  events.put(e.getCode(), e);
+                                  events.put(o.getCode(), o);
                                }
                                eventViewer.setInput(events.values().toArray());
                        };
index d56187b..049032b 100644 (file)
@@ -39,7 +39,7 @@ import org.eclipse.ui.forms.events.HyperlinkEvent;
 import org.eclipse.ui.forms.widgets.FormToolkit;
 import org.eclipse.ui.forms.widgets.ImageHyperlink;
 import org.netxms.client.NXCSession;
-import org.netxms.client.events.EventTemplate;
+import org.netxms.client.events.EventObject;
 import org.netxms.ui.eclipse.console.resources.SharedIcons;
 import org.netxms.ui.eclipse.eventmanager.widgets.EventSelector;
 import org.netxms.ui.eclipse.serverconfig.Messages;
@@ -407,9 +407,9 @@ public class LogParserRuleEditor extends DashboardComposite
                        }
                        catch(NumberFormatException e)
                        {
-                               EventTemplate t = ((NXCSession)ConsoleSharedData.getSession()).findEventTemplateByName(rule.getEvent().getEvent());
-                               if (t != null)
-                                       eventCode = t.getCode();
+                               EventObject o = ((NXCSession)ConsoleSharedData.getSession()).findEventObjectByName(rule.getEvent().getEvent());
+                               if (o != null)
+                                       eventCode = o.getCode();
                        }
                }
                
index f1c9f84..0d62b10 100644 (file)
@@ -1300,7 +1300,6 @@ typedef struct
    String charData[MAX_STACK_DEPTH];
    bool trimValue[MAX_STACK_DEPTH];
    bool merge;
-   bool expandEnv;
 } XML_PARSER_STATE;
 
 /**
@@ -1398,7 +1397,7 @@ static void EndElement(void *userData, const char *name)
       ps->level--;
       if (ps->trimValue[ps->level])
          ps->charData[ps->level].trim();
-      ps->stack[ps->level]->addValuePreallocated(ExpandValue(ps->charData[ps->level], true, ps->expandEnv));
+      ps->stack[ps->level]->addValuePreallocated(ExpandValue(ps->charData[ps->level], true, ps->config->isExpansionAllowed()));
    }
 }
 
@@ -1431,7 +1430,6 @@ bool Config::loadXmlConfigFromMemory(const char *xml, int xmlSize, const TCHAR *
    state.parser = parser;
    state.file = (name != NULL) ? name : _T("<mem>");
    state.merge = merge;
-   state.expandEnv = m_allowMacroExpansion;
 
    bool success = (XML_Parse(parser, xml, xmlSize, TRUE) != XML_STATUS_ERROR);
    if (!success)
index fc35567..f888254 100644 (file)
@@ -445,8 +445,8 @@ void DCItem::checkThresholds(ItemValue &value)
             {
                PostDciEventWithNames(t->getEventCode(), m_owner->getId(), m_id, "ssssisds",
                                           s_paramNamesReach, m_name, m_description, t->getStringValue(),
-                  (const TCHAR *)checkValue, m_id, m_instance, 0, (const TCHAR *)value);
-                                  EventTemplate *evt = FindEventTemplateByCode(t->getEventCode());
+                  (const TCHAR *)checkValue, m_id, m_instance, 0);
+                                  EventTemplate *evt = (EventTemplate *)FindEventObjectByCode(t->getEventCode());
                                   if (evt != NULL)
                                   {
                                           t->markLastEvent(evt->getSeverity());
@@ -475,8 +475,13 @@ void DCItem::checkThresholds(ItemValue &value)
                                   {
                                           PostDciEventWithNames(t->getEventCode(), m_owner->getId(), m_id, "ssssisds",
                                                   s_paramNamesReach, m_name, m_description, t->getStringValue(),
+<<<<<<< HEAD
                                                   (const TCHAR *)checkValue, m_id, m_instance, 1, (const TCHAR *)value);
                                           EventTemplate *evt = FindEventTemplateByCode(t->getEventCode());
+=======
+                                                  (const TCHAR *)checkValue, m_id, m_instance, 1);
+                                          EventTemplate *evt = (EventTemplate *)FindEventObjectByCode(t->getEventCode());
+>>>>>>> 771ed10dd... Implemented event group functionality. Fixes #NX-1102
                                           if (evt != NULL)
                                           {
                                                   t->markLastEvent(evt->getSeverity());
@@ -775,7 +780,7 @@ void DCItem::processNewError(bool noInstance, time_t now)
                PostDciEventWithNames(t->getEventCode(), m_owner->getId(), m_id, "ssssisd",
                                           s_paramNamesReach, m_name, m_description, _T(""), _T(""),
                   m_id, m_instance, 0);
-               EventTemplate *evt = FindEventTemplateByCode(t->getEventCode());
+               EventTemplate *evt = (EventTemplate *)FindEventObjectByCode(t->getEventCode());
                                   if (evt != NULL)
                                   {
                                           t->markLastEvent(evt->getSeverity());
@@ -800,7 +805,7 @@ void DCItem::processNewError(bool noInstance, time_t now)
                                           PostDciEventWithNames(t->getEventCode(), m_owner->getId(), m_id, "ssssisd",
                                                   s_paramNamesReach, m_name, m_description, _T(""), _T(""),
                                                   m_id, m_instance, 1);
-                                          EventTemplate *evt = FindEventTemplateByCode(t->getEventCode());
+                                          EventTemplate *evt = (EventTemplate *)FindEventObjectByCode(t->getEventCode());
                                           if (evt != NULL)
                                           {
                                                   t->markLastEvent(evt->getSeverity());
index 576277c..37f08f5 100644 (file)
@@ -65,7 +65,7 @@ BOOL EF_ProcessMessage(ISCSession *session, NXCPMessage *request, NXCPMessage *r
                        if (name != NULL)
                        {
                                DbgPrintf(5, _T("Event specified by name (%s)"), name);
-                               EventTemplate *pt = FindEventTemplateByName(name);
+                               EventTemplate *pt = (EventTemplate *)FindEventObjectByName(name);
                                if (pt != NULL)
                                {
                                        code = pt->getCode();
index 48f35a8..d419444 100644 (file)
@@ -70,11 +70,11 @@ EPRule::EPRule(ConfigEntry *config)
       m_pdwEventList = (UINT32 *)malloc(sizeof(UINT32) * events->size());
       for(int i = 0; i < events->size(); i++)
       {
-         EventTemplate *e = FindEventTemplateByName(events->get(i)->getSubEntryValue(_T("name"), 0, _T("<unknown>")));
-         if (e != NULL)
+         EventObject *o = FindEventObjectByName(events->get(i)->getSubEntryValue(_T("name"), 0, _T("<unknown>")));
+         if (o != NULL)
          {
-            m_pdwEventList[m_dwNumEvents++] = e->getCode();
-            e->decRefCount();
+            m_pdwEventList[m_dwNumEvents++] = o->getCode();
+            o->decRefCount();
          }
       }
    }
@@ -399,7 +399,12 @@ bool EPRule::matchEvent(UINT32 dwEventCode)
       for(i = 0; i < m_dwNumEvents; i++)
          if (m_pdwEventList[i] & GROUP_FLAG_BIT)
          {
-            /* TODO: check group membership */
+            EventGroup *g = (EventGroup *)FindEventObjectByCode(m_pdwEventList[i]);
+            if (g != NULL && g->isMember(dwEventCode))
+            {
+               bMatch = true;
+               break;
+            }
          }
          else
          {
index 9b888ae..1b855e9 100644 (file)
@@ -31,21 +31,93 @@ EventPolicy *g_pEventPolicy = NULL;
 /**
  * Static data
  */
-static RefCountHashMap<UINT32, EventTemplate> m_eventTemplates(true);
+static RefCountHashMap<UINT32, EventObject> m_eventObjects(true);
 static RWLOCK m_rwlockTemplateAccess;
 
 /**
- * Create event template from DB record
+ * Create event object from DB record
  */
-EventTemplate::EventTemplate(DB_RESULT hResult, int row)
+EventObject::EventObject(DB_RESULT hResult, int row)
 {
    m_code = DBGetFieldULong(hResult, row, 0);
-   m_severity = DBGetFieldLong(hResult, row, 1);
-   m_flags = DBGetFieldLong(hResult, row, 2);
-   m_messageTemplate = DBGetField(hResult, row, 3, NULL, 0);
-   m_description = DBGetField(hResult, row, 4, NULL, 0);
-   DBGetField(hResult, row, 5, m_name, MAX_EVENT_NAME);
-   m_guid = DBGetFieldGUID(hResult, row, 6);
+   m_description = DBGetField(hResult, row, 1, NULL, 0);
+   DBGetField(hResult, row, 2, m_name, MAX_EVENT_NAME);
+   m_guid = DBGetFieldGUID(hResult, row, 3);
+}
+
+/**
+ * Create event object from message
+ */
+EventObject::EventObject(NXCPMessage *msg)
+{
+   m_code = 0;
+   m_description = msg->getFieldAsString(VID_DESCRIPTION);
+   msg->getFieldAsString(VID_NAME, m_name, MAX_EVENT_NAME);
+   m_guid = uuid::generate();
+}
+
+/**
+ * Event object destructor
+ */
+EventObject::~EventObject()
+{
+   free(m_description);
+}
+
+/**
+ * Modify event object from message
+ */
+void EventObject::modifyFromMessage(NXCPMessage *msg)
+{
+   m_code = msg->getFieldAsUInt32(VID_EVENT_CODE);
+   free(m_description);
+   m_description = msg->getFieldAsString(VID_DESCRIPTION);
+   msg->getFieldAsString(VID_NAME, m_name, MAX_EVENT_NAME);
+}
+
+/**
+ * Fill message with event object data
+ */
+void EventObject::fillMessage(NXCPMessage *msg, UINT32 base) const
+{
+   msg->setField(base + 1, m_code);
+   msg->setField(base + 2, m_description);
+   msg->setField(base + 3, m_name);
+}
+
+/**
+ * Convert event object to JSON
+ */
+json_t *EventObject::toJson() const
+{
+   json_t *root = json_object();
+
+   json_object_set_new(root, "name", json_string_t(m_name));
+   json_object_set_new(root, "code", json_integer(m_code));
+   json_object_set_new(root, "description", json_string_t(m_description));
+
+   return root;
+}
+
+/**
+ * Create event template from DB record
+ */
+EventTemplate::EventTemplate(DB_RESULT hResult, int row) : EventObject(hResult, row)
+{
+   m_severity = DBGetFieldLong(hResult, row, 4);
+   m_flags = DBGetFieldLong(hResult, row, 5);
+   m_messageTemplate = DBGetField(hResult, row, 6, NULL, 0);
+}
+
+/**
+ * Create event template from message
+ */
+EventTemplate::EventTemplate(NXCPMessage *msg) : EventObject(msg)
+{
+   m_code = CreateUniqueId(IDG_EVENT);
+   m_severity = msg->getFieldAsInt32(VID_SEVERITY);
+   m_flags = msg->getFieldAsInt32(VID_FLAGS);
+   m_messageTemplate = msg->getFieldAsString(VID_MESSAGE);
 }
 
 /**
@@ -54,7 +126,6 @@ EventTemplate::EventTemplate(DB_RESULT hResult, int row)
 EventTemplate::~EventTemplate()
 {
    free(m_messageTemplate);
-   free(m_description);
 }
 
 /**
@@ -62,17 +133,264 @@ EventTemplate::~EventTemplate()
  */
 json_t *EventTemplate::toJson() const
 {
-   json_t *root = json_object();
-   json_object_set_new(root, "code", json_integer(m_code));
+   json_t *root = EventObject::toJson();
    json_object_set_new(root, "guid", m_guid.toJson());
    json_object_set_new(root, "severity", json_integer(m_severity));
    json_object_set_new(root, "flags", json_integer(m_flags));
    json_object_set_new(root, "message", json_string_t(m_messageTemplate));
-   json_object_set_new(root, "description", json_string_t(m_description));
+
+   return root;
+}
+
+/**
+ * Modify event template from message
+ */
+void EventTemplate::modifyFromMessage(NXCPMessage *msg)
+{
+   EventObject::modifyFromMessage(msg);
+   m_severity = msg->getFieldAsInt32(VID_SEVERITY);
+   m_flags = msg->getFieldAsInt32(VID_FLAGS);
+   free(m_messageTemplate);
+   m_messageTemplate = msg->getFieldAsString(VID_MESSAGE);
+}
+
+/**
+ * Fill message with event template data
+ */
+void EventTemplate::fillMessage(NXCPMessage *msg, UINT32 base) const
+{
+   EventObject::fillMessage(msg, base);
+   msg->setField(base + 4, m_severity);
+   msg->setField(base + 5, m_flags);
+   msg->setField(base + 6, m_messageTemplate);
+}
+
+/**
+ * Save event template to database
+ */
+bool EventTemplate::saveToDatabase() const
+{
+   DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
+   DB_STATEMENT hStmt;
+   bool success = false;
+
+   bool recordExists = IsDatabaseRecordExist(hdb, _T("event_cfg"), _T("event_code"), m_code);
+   if (recordExists)
+      hStmt = DBPrepare(hdb, _T("UPDATE event_cfg SET event_name=?,severity=?,flags=?,message=?,description=? WHERE event_code=?"));
+   else
+      hStmt = DBPrepare(hdb, _T("INSERT INTO event_cfg (event_name,severity,flags,message,description,event_code,guid) VALUES (?,?,?,?,?,?,?)"));
+
+   if (hStmt != NULL)
+   {
+      DBBind(hStmt, 1, DB_SQLTYPE_VARCHAR, m_name, DB_BIND_STATIC);
+      DBBind(hStmt, 2, DB_SQLTYPE_INTEGER, m_severity);
+      DBBind(hStmt, 3, DB_SQLTYPE_INTEGER, m_flags);
+      DBBind(hStmt, 4, DB_SQLTYPE_VARCHAR, m_messageTemplate, DB_BIND_STATIC, MAX_EVENT_MSG_LENGTH - 1);
+      DBBind(hStmt, 5, DB_SQLTYPE_TEXT, m_description, DB_BIND_STATIC);
+      DBBind(hStmt, 6, DB_SQLTYPE_INTEGER, m_code);
+
+      if (!recordExists)
+      {
+         DBBind(hStmt, 7, DB_SQLTYPE_VARCHAR, uuid::generate());
+      }
+      success = DBExecute(hStmt);
+      DBFreeStatement(hStmt);
+   }
+   DBConnectionPoolReleaseConnection(hdb);
+
+   return success;
+}
+
+/**
+ * Create event group from message
+ */
+EventGroup::EventGroup(NXCPMessage *msg) : EventObject(msg)
+{
+   m_code = CreateUniqueId(IDG_EVENT_GROUP);
+   m_eventCodeList = new IntegerArray<UINT32>;
+   msg->getFieldAsInt32Array(VID_EVENT_LIST, m_eventCodeList);
+}
+
+/**
+ * Create event group from DB
+ */
+EventGroup::EventGroup(DB_RESULT result, int row, IntegerArray<UINT32> *memberCache) : EventObject(result, row)
+{
+   m_eventCodeList = new IntegerArray<UINT32>(16, 16);
+   int i = 0;
+   while((i < memberCache->size()) && (memberCache->get(i) != m_code))
+      i += 2;
+   while((i < memberCache->size()) && (memberCache->get(i) == m_code))
+   {
+      m_eventCodeList->add(memberCache->get(i + 1));
+      i += 2;
+   }
+}
+
+/**
+ * Event group destructor
+ */
+EventGroup::~EventGroup()
+{
+   free(m_eventCodeList);
+}
+
+/**
+ * Check if event is a member of specific group
+ */
+static bool CheckGroupMembership(UINT32 eventCode, UINT32 groupId)
+{
+   if (!(groupId & GROUP_FLAG_BIT))
+      return false;
+
+   EventGroup *g = (EventGroup *)m_eventObjects.get(groupId);
+   if (g != NULL)
+   {
+      for(int i = 0; i < g->getMemberCount(); i++)
+      {
+         if (eventCode == g->getMember(i))
+            return true;
+         if (CheckGroupMembership(eventCode, g->getMember(i)))
+            return true;
+      }
+   }
+
+   return false;
+}
+/**
+ * Modify event template from message
+ */
+void EventGroup::modifyFromMessage(NXCPMessage *msg)
+{
+   EventObject::modifyFromMessage(msg);
+   IntegerArray<UINT32> eventCodeList;
+   msg->getFieldAsInt32Array(VID_EVENT_LIST, &eventCodeList);
+   m_eventCodeList->clear();
+   for(int i = 0; i < eventCodeList.size(); i++)
+   {
+      if (!m_eventCodeList->contains(eventCodeList.get(i)) &&
+         !CheckGroupMembership(m_code, eventCodeList.get(i)) &&
+         !CheckGroupMembership(eventCodeList.get(i), m_code))
+      {
+         m_eventCodeList->add(eventCodeList.get(i));
+      }
+   }
+}
+
+/**
+ * Fill message with event group data
+ */
+void EventGroup::fillMessage(NXCPMessage *msg, UINT32 base) const
+{
+   EventObject::fillMessage(msg, base);
+   msg->setFieldFromInt32Array(base + 4, m_eventCodeList);
+}
+
+/**
+ * Save event group to database
+ */
+bool EventGroup::saveToDatabase() const
+{
+   DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
+
+   bool success = DBBegin(hdb);
+   if (success)
+   {
+      DB_STATEMENT hStmt;
+      bool recordExists = IsDatabaseRecordExist(hdb, _T("event_groups"), _T("id"), m_code);
+      if (recordExists)
+         hStmt = DBPrepare(hdb, _T("UPDATE event_groups SET name=?,description=? WHERE id=?"));
+      else
+         hStmt = DBPrepare(hdb, _T("INSERT INTO event_groups (name,description,id,guid) VALUES (?,?,?,?)"));
+
+      if (hStmt != NULL)
+      {
+         DBBind(hStmt, 1, DB_SQLTYPE_VARCHAR, m_name, DB_BIND_STATIC);
+         DBBind(hStmt, 2, DB_SQLTYPE_TEXT, m_description, DB_BIND_STATIC);
+         DBBind(hStmt, 3, DB_SQLTYPE_INTEGER, m_code);
+         if (!recordExists)
+            DBBind(hStmt, 4, DB_SQLTYPE_INTEGER, m_guid);
+
+         success = DBExecute(hStmt);
+         DBFreeStatement(hStmt);
+      }
+
+      if (success)
+      {
+         hStmt = DBPrepare(hdb, _T("DELETE FROM event_group_members WHERE group_id=?"));
+         if (hStmt != NULL)
+         {
+            DBBind(hStmt, 1, DB_SQLTYPE_INTEGER, m_code);
+            success = DBExecute(hStmt);
+            DBFreeStatement(hStmt);
+         }
+         else
+            success = false;
+      }
+
+      if (success)
+      {
+         hStmt = DBPrepare(hdb, _T("INSERT INTO event_group_members (group_id,event_code) VALUES (?,?)"));
+         if (hStmt != NULL)
+         {
+            DBBind(hStmt, 1, DB_SQLTYPE_INTEGER, m_code);
+            for(int i = 0; i < m_eventCodeList->size() && success; i++)
+            {
+               DBBind(hStmt, 2, DB_SQLTYPE_INTEGER, m_eventCodeList->get(i));
+               success = DBExecute(hStmt);
+            }
+            DBFreeStatement(hStmt);
+         }
+      }
+
+      if (success)
+         success = DBCommit(hdb);
+      else
+         DBRollback(hdb);
+   }
+   DBConnectionPoolReleaseConnection(hdb);
+
+   return success;
+}
+
+/**
+ * Convert event group to JSON
+ */
+json_t *EventGroup::toJson() const
+{
+   json_t *root = EventObject::toJson();
+
+   json_t *groupList =  json_array();
+   for(int i = 0; i < m_eventCodeList->size(); i++)
+      json_array_append_new(groupList, json_integer(m_eventCodeList->get(i)));
+   json_object_set_new(root, "groups", groupList);
+
    return root;
 }
 
 /**
+ * Check if event object is member of group (recursive)
+ */
+bool EventGroup::isMember(UINT32 eventCode)
+{
+   if (m_eventCodeList->contains(eventCode))
+      return true;
+
+   for(int i = 0; i < m_eventCodeList->size(); i++)
+   {
+      if (m_eventCodeList->get(i) & GROUP_FLAG_BIT)
+      {
+         EventGroup *g = (EventGroup*)FindEventObjectByCode(m_eventCodeList->get(i));
+         if (g != NULL)
+            return g->isMember(m_eventCodeList->get(i));
+         return false;
+      }
+   }
+
+   return false;
+}
+
+/**
  * Default constructor for event
  */
 Event::Event()
@@ -772,19 +1090,43 @@ static bool LoadEvents()
 {
    bool success = false;
    DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
-   DB_RESULT hResult = DBSelect(hdb, _T("SELECT event_code,severity,flags,message,description,event_name,guid FROM event_cfg"));
+   DB_RESULT hResult = DBSelect(hdb, _T("SELECT event_code,description,event_name,guid,severity,flags,message FROM event_cfg"));
    if (hResult != NULL)
    {
       int count = DBGetNumRows(hResult);
       for(int i = 0; i < count; i++)
       {
          EventTemplate *t = new EventTemplate(hResult, i);
-         m_eventTemplates.set(t->getCode(), t);
+         m_eventObjects.set(t->getCode(), t);
          t->decRefCount();
       }
-
       DBFreeResult(hResult);
-      success = true;
+
+      IntegerArray<UINT32> memberCache(256, 256);
+      hResult = DBSelect(hdb, _T("SELECT group_id,event_code FROM event_group_members ORDER BY group_id"));
+      if (hResult != NULL)
+      {
+         int count = DBGetNumRows(hResult);
+         for(int i = 0; i < count; i++)
+         {
+            memberCache.add(DBGetFieldULong(hResult, i, 0));
+            memberCache.add(DBGetFieldULong(hResult, i, 1));
+         }
+         DBFreeResult(hResult);
+      }
+
+      hResult = DBSelect(hdb, _T("SELECT id,description,name,guid FROM event_groups"));
+      if (hResult != NULL)
+      {
+         UINT32 numRows = DBGetNumRows(hResult);
+         for(int i = 0; i < numRows; i++)
+         {
+            EventGroup *g = new EventGroup(hResult, i, &memberCache);
+            m_eventObjects.set(g->getCode(), g);
+            g->decRefCount();
+         }
+         success = true;
+      }
    }
    else
    {
@@ -802,7 +1144,7 @@ BOOL InitEventSubsystem()
 {
    BOOL bSuccess;
 
-   // Create template access mutex
+   // Create object access mutex
    m_rwlockTemplateAccess = RWLockCreate();
 
    // Create event queue
@@ -842,18 +1184,18 @@ void ShutdownEventSubsystem()
 void ReloadEvents()
 {
    RWLockWriteLock(m_rwlockTemplateAccess, INFINITE);
-   m_eventTemplates.clear();
+   m_eventObjects.clear();
    LoadEvents();
    RWLockUnlock(m_rwlockTemplateAccess);
 }
 
 /**
- * Delete event template from list
+ * Delete event object from list
  */
-void DeleteEventTemplateFromList(UINT32 eventCode)
+void DeleteEventObjectFromList(UINT32 eventCode)
 {
    RWLockWriteLock(m_rwlockTemplateAccess, INFINITE);
-   m_eventTemplates.remove(eventCode);
+   m_eventObjects.remove(eventCode);
    RWLockUnlock(m_rwlockTemplateAccess);
 }
 
@@ -887,7 +1229,7 @@ static bool RealPostEvent(Queue *queue, UINT64 *eventId, UINT32 eventCode, UINT3
 
    RWLockReadLock(m_rwlockTemplateAccess, INFINITE);
 
-   eventTemplate = m_eventTemplates.get(eventCode);
+   eventTemplate = (EventTemplate *)m_eventObjects.get(eventCode);
    if (eventTemplate != NULL)
    {
       // Template found, create new event
@@ -1227,23 +1569,38 @@ void CreateNXMPEventRecord(String &str, UINT32 eventCode)
    RWLockReadLock(m_rwlockTemplateAccess, INFINITE);
 
    // Find event template
-   EventTemplate *p = m_eventTemplates.get(eventCode);
-   if (p != NULL)
+   EventObject *o = m_eventObjects.get(eventCode);
+   if (o != NULL)
    {
       str.appendFormattedString(_T("\t\t<event id=\"%d\">\n")
-                             _T("\t\t\t<name>%s</name>\n")
-                             _T("\t\t\t<guid>%s</guid>\n")
-                             _T("\t\t\t<code>%d</code>\n")
-                             _T("\t\t\t<severity>%d</severity>\n")
-                             _T("\t\t\t<flags>%d</flags>\n")
-                             _T("\t\t\t<message>%s</message>\n")
-                             _T("\t\t\t<description>%s</description>\n")
-                             _T("\t\t</event>\n"),
-                             p->getCode(), (const TCHAR *)EscapeStringForXML2(p->getName()),
-                             (const TCHAR *)p->getGuid().toString(), p->getCode(), p->getSeverity(),
-                             p->getFlags(), (const TCHAR *)EscapeStringForXML2(p->getMessageTemplate()),
-                             (const TCHAR *)EscapeStringForXML2(p->getDescription()));
-      p->decRefCount();
+                                      _T("\t\t\t<name>%s</name>\n")
+                                      _T("\t\t\t<code>%d</code>\n")
+                                      _T("\t\t\t<description>%s</description>\n"),
+                                      o->getCode(), (const TCHAR *)EscapeStringForXML2(o->getName()),
+                                     (const TCHAR *)EscapeStringForXML2(o->getDescription()));
+      if (eventCode & GROUP_FLAG_BIT)
+      {
+         str.appendFormattedString(_T("\t\t\t<members>\n"));
+         for(int i = 0; i < ((EventGroup *) o)->getMemberCount(); i++)
+         {
+            str.appendFormattedString(_T("\t\t\t\t<code>%d</code>\n"),
+                                     ((EventGroup *) o)->getMember(i));
+         }
+         str.appendFormattedString(_T("\t\t\t</members>\n"));
+      }
+      else
+      {
+         str.appendFormattedString(_T("\t\t\t<guid>%s</guid>\n")
+                                _T("\t\t\t<severity>%d</severity>\n")
+                                _T("\t\t\t<flags>%d</flags>\n")
+                                _T("\t\t\t<message>%s</message>\n")
+                                _T("\t\t</event>\n"),
+                                (const TCHAR *)((EventTemplate *)o)->getGuid().toString(), o->getCode(),
+                                ((EventTemplate *)o)->getSeverity(), ((EventTemplate *)o)->getFlags(),
+                                (const TCHAR *)EscapeStringForXML2(((EventTemplate *)o)->getMessageTemplate()),
+                                (const TCHAR *)EscapeStringForXML2(((EventTemplate *)o)->getDescription()));
+      }
+      o->decRefCount();
    }
 
    RWLockUnlock(m_rwlockTemplateAccess);
@@ -1258,11 +1615,11 @@ bool EventNameFromCode(UINT32 eventCode, TCHAR *buffer)
 
    RWLockReadLock(m_rwlockTemplateAccess, INFINITE);
 
-   EventTemplate *p = m_eventTemplates.get(eventCode);
-   if (p != NULL)
+   EventObject *o = m_eventObjects.get(eventCode);
+   if (o != NULL)
    {
-      _tcscpy(buffer, p->getName());
-      p->decRefCount();
+      _tcscpy(buffer, o->getName());
+      o->decRefCount();
       bRet = true;
    }
    else
@@ -1275,31 +1632,31 @@ bool EventNameFromCode(UINT32 eventCode, TCHAR *buffer)
 }
 
 /**
- * Find event template by code - suitable for external call
+ * Find event object by code - suitable for external call
  */
-EventTemplate *FindEventTemplateByCode(UINT32 eventCode)
+EventObject *FindEventObjectByCode(UINT32 eventCode)
 {
    RWLockReadLock(m_rwlockTemplateAccess, INFINITE);
-   EventTemplate *p = m_eventTemplates.get(eventCode);
+   EventObject *o = m_eventObjects.get(eventCode);
    RWLockUnlock(m_rwlockTemplateAccess);
-   return p;
+   return o;
 }
 
 /**
- * Find event template by name - suitable for external call
+ * Find event object by name - suitable for external call
  */
-EventTemplate *FindEventTemplateByName(const TCHAR *name)
+EventObject *FindEventObjectByName(const TCHAR *name)
 {
-   EventTemplate *result = NULL;
+   EventObject *result = NULL;
 
    RWLockReadLock(m_rwlockTemplateAccess, INFINITE);
-   Iterator<EventTemplate> *it = m_eventTemplates.iterator();
+   Iterator<EventObject> *it = m_eventObjects.iterator();
    while(it->hasNext())
    {
-      EventTemplate *t = it->next();
-      if (!_tcscmp(t->getName(), name))
+      EventObject *o = it->next();
+      if (!_tcscmp(o->getName(), name))
       {
-         result = t;
+         result = o;
          result->incRefCount();
          break;
       }
@@ -1315,11 +1672,11 @@ EventTemplate *FindEventTemplateByName(const TCHAR *name)
  */
 UINT32 NXCORE_EXPORTABLE EventCodeFromName(const TCHAR *name, UINT32 defaultValue)
 {
-       EventTemplate *p = FindEventTemplateByName(name);
-       if (p == NULL)
+   EventObject *o = FindEventObjectByName(name);
+       if (o == NULL)
           return defaultValue;
-       UINT32 code = p->getCode();
-       p->decRefCount();
+       UINT32 code = o->getCode();
+       o->decRefCount();
        return code;
 }
 
@@ -1340,3 +1697,171 @@ const TCHAR NXCORE_EXPORTABLE *GetStatusAsText(int status, bool allCaps)
       return ((status >= STATUS_NORMAL) && (status <= STATUS_TESTING)) ? statusTextSmall[status] : _T("INTERNAL ERROR");
    }
 }
+
+/**
+ * Callback for sending event configuration change notifications
+ */
+static void SendEventDBChangeNotification(ClientSession *session, void *arg)
+{
+   if (session->isAuthenticated() &&
+       (session->checkSysAccessRights(SYSTEM_ACCESS_VIEW_EVENT_DB) ||
+        session->checkSysAccessRights(SYSTEM_ACCESS_EDIT_EVENT_DB) ||
+        session->checkSysAccessRights(SYSTEM_ACCESS_EPP)))
+      session->postMessage((NXCPMessage *)arg);
+}
+
+/**
+ * Update or create new event object from request
+ */
+UINT32 UpdateEventObject(NXCPMessage *request, NXCPMessage *response, json_t **oldValue, json_t **newValue)
+{
+   TCHAR name[MAX_EVENT_NAME] = _T("");
+   request->getFieldAsString(VID_NAME, name, MAX_EVENT_NAME);
+   if (!IsValidObjectName(name, TRUE))
+      return RCC_INVALID_OBJECT_NAME;
+
+   EventObject *obj;
+   UINT32 eventCode = request->getFieldAsUInt32(VID_EVENT_CODE);
+   RWLockWriteLock(m_rwlockTemplateAccess, INFINITE);
+
+   if (eventCode == 0)
+   {
+      if (request->getFieldAsBoolean(VID_IS_GROUP))
+         obj = new EventGroup(request);
+      else
+         obj = new EventTemplate(request);
+      m_eventObjects.set(obj->getCode(), obj);
+      *oldValue = NULL;
+   }
+   else
+   {
+      obj = m_eventObjects.get(eventCode);
+      if (obj == NULL)
+      {
+         RWLockUnlock(m_rwlockTemplateAccess);
+         return RCC_INVALID_EVENT_CODE;
+      }
+      *oldValue = obj->toJson();
+      obj->modifyFromMessage(request);
+   }
+   *newValue = obj->toJson();
+   bool success = obj->saveToDatabase();
+   if (success)
+   {
+      NXCPMessage nmsg;
+      nmsg.setCode(CMD_EVENT_DB_UPDATE);
+      nmsg.setField(VID_NOTIFICATION_CODE, (WORD)NX_NOTIFY_ETMPL_CHANGED);
+      obj->fillMessage(&nmsg, VID_ELEMENT_LIST_BASE);
+      EnumerateClientSessions(SendEventDBChangeNotification, &nmsg);
+
+      response->setField(VID_EVENT_CODE, obj->getCode());
+   }
+
+   RWLockUnlock(m_rwlockTemplateAccess);
+
+   if (!success)
+   {
+      if (*oldValue != NULL)
+      {
+         json_decref(*oldValue);
+         *oldValue = NULL;
+      }
+      json_decref(*newValue);
+      *newValue = NULL;
+      return RCC_DB_FAILURE;
+   }
+
+   return RCC_SUCCESS;
+}
+
+/**
+ * Delete event template
+ */
+UINT32 DeleteEventObject(UINT32 eventCode)
+{
+   UINT32 rcc = RCC_SUCCESS;
+   DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
+   DB_STATEMENT hStmt;
+
+   RWLockWriteLock(m_rwlockTemplateAccess, INFINITE);
+   if (eventCode & GROUP_FLAG_BIT)
+   {
+      if(m_eventObjects.contains(eventCode))
+      {
+         bool success = DBBegin(hdb);
+         if (success)
+         {
+            hStmt = DBPrepare(hdb, _T("DELETE FROM event_groups WHERE id=?"));
+            if (hStmt != NULL)
+            {
+               DBBind(hStmt, 1, DB_SQLTYPE_INTEGER, eventCode);
+               success = DBExecute(hStmt);
+               DBFreeStatement(hStmt);
+            }
+            else
+               success = false;
+            if (success)
+            {
+               hStmt = DBPrepare(hdb, _T("DELETE FROM event_group_members WHERE group_id=?"));
+               if (hStmt != NULL)
+               {
+                  DBBind(hStmt, 1, DB_SQLTYPE_INTEGER, eventCode);
+                  success = DBExecute(hStmt);
+                  DBFreeStatement(hStmt);
+               }
+               else
+                  success = false;
+            }
+            if (success)
+               success = DBCommit(hdb);
+            else
+               DBRollback(hdb);
+         }
+         rcc = success ? RCC_SUCCESS : RCC_DB_FAILURE;
+      }
+   }
+   else if (m_eventObjects.contains(eventCode))
+   {
+      hStmt = DBPrepare(hdb, _T("DELETE FROM event_cfg WHERE event_code=?"));
+      if (hStmt != NULL)
+      {
+         DBBind(hStmt, 1, DB_SQLTYPE_INTEGER, eventCode);
+         rcc = DBExecute(hStmt) ? RCC_SUCCESS : RCC_DB_FAILURE;
+         DBFreeStatement(hStmt);
+      }
+   }
+   else
+      rcc = RCC_INVALID_EVENT_CODE;
+
+   if (rcc == RCC_SUCCESS)
+   {
+      m_eventObjects.remove(eventCode);
+      NXCPMessage nmsg;
+      nmsg.setCode(CMD_EVENT_DB_UPDATE);
+      nmsg.setField(VID_NOTIFICATION_CODE, (WORD)NX_NOTIFY_ETMPL_DELETED);
+      nmsg.setField(VID_EVENT_CODE, eventCode);
+      EnumerateClientSessions(SendEventDBChangeNotification, &nmsg);
+   }
+   RWLockUnlock(m_rwlockTemplateAccess);
+
+   DBConnectionPoolReleaseConnection(hdb);
+   return rcc;
+}
+
+/**
+ * Get event configuration
+ */
+void GetEventConfiguration(NXCPMessage *msg)
+{
+   RWLockWriteLock(m_rwlockTemplateAccess, INFINITE);
+   UINT32 base = VID_ELEMENT_LIST_BASE;
+   msg->setField(VID_NUM_EVENTS, m_eventObjects.size());
+   Iterator<EventObject> *it = m_eventObjects.iterator();
+   while(it->hasNext())
+   {
+      EventObject *o = it->next();
+      o->fillMessage(msg, base);
+      base += 10;
+   }
+   RWLockUnlock(m_rwlockTemplateAccess);
+}
index 5708a0c..d95953c 100644 (file)
@@ -27,7 +27,7 @@
  */
 static bool IsEventExist(const TCHAR *name, Config *config)
 {
-       if (FindEventTemplateByName(name) != NULL)
+       if (FindEventObjectByName(name) != NULL)
                return true;
 
        ConfigEntry *eventsRoot = config->getEntry(_T("/events"));
@@ -154,10 +154,10 @@ bool ValidateConfig(Config *config, UINT32 flags, TCHAR *errorText, int errorTex
                                ConfigEntry *e = event->findEntry(_T("name"));
                                if (e != NULL)
                                {
-                                  EventTemplate *pEvent = FindEventTemplateByName(e->getValue());
-                                       if (pEvent != NULL)
+                                  EventObject *eventObject = FindEventObjectByName(e->getValue());
+                                       if (eventObject != NULL)
                                        {
-                                          pEvent->decRefCount();
+                                          eventObject->decRefCount();
                                                if (!(flags & CFG_IMPORT_REPLACE_EVENT_BY_NAME))
                                                {
                                                        _sntprintf(errorText, errorTextLen, _T("Event with name %s already exist"), e->getValue());
@@ -173,17 +173,17 @@ bool ValidateConfig(Config *config, UINT32 flags, TCHAR *errorText, int errorTex
                        }
                        else
                        {
-                          EventTemplate *pEvent = FindEventTemplateByCode(code);
-                               if (pEvent != NULL)
+                          EventObject *eventObject = FindEventObjectByCode(code);
+                               if (eventObject != NULL)
                                {
                                        if (!(flags & CFG_IMPORT_REPLACE_EVENT_BY_CODE))
                                        {
                                                _sntprintf(errorText, errorTextLen, _T("Event with code %d already exist (existing event name: %s; new event name: %s)"),
-                                                          pEvent->getCode(), pEvent->getName(), event->getSubEntryValue(_T("name"), 0, _T("<unnamed>")));
-                                               pEvent->decRefCount();
+                                                        eventObject->getCode(), eventObject->getName(), event->getSubEntryValue(_T("name"), 0, _T("<unnamed>")));
+                                               eventObject->decRefCount();
                                                goto stop_processing;
                                        }
-               pEvent->decRefCount();
+                                       eventObject->decRefCount();
                                }
                        }
                }
@@ -328,8 +328,8 @@ static UINT32 ImportEvent(ConfigEntry *event)
 static UINT32 ImportTrap(ConfigEntry *trap) // TODO transactions needed?
 {
    UINT32 rcc = RCC_INTERNAL_ERROR;
-       EventTemplate *event = FindEventTemplateByName(trap->getSubEntryValue(_T("event"), 0, _T("")));
-       if (event == NULL)
+       EventObject *eventObject = FindEventObjectByName(trap->getSubEntryValue(_T("event"), 0, _T("")));
+       if (eventObject == NULL)
                return rcc;
 
        uuid guid = trap->getSubEntryValueAsUUID(_T("guid"));
@@ -339,7 +339,7 @@ static UINT32 ImportTrap(ConfigEntry *trap) // TODO transactions needed?
       nxlog_debug(4, _T("ImportTrap: GUID not found in config, generated GUID %s"), (const TCHAR *)guid.toString());
    }
    UINT32 id = ResolveTrapGuid(guid);
-       SNMPTrapConfiguration *trapCfg = new SNMPTrapConfiguration(trap, guid, id, event->getCode());
+       SNMPTrapConfiguration *trapCfg = new SNMPTrapConfiguration(trap, guid, id, eventObject->getCode());
 
        if (!trapCfg->getOid().isValid())
        {
index 74249b5..e70aadb 100644 (file)
@@ -693,7 +693,7 @@ void ClientSession::processingThread()
             deleteAlarmCategory(pMsg);
             break;
          case CMD_LOAD_EVENT_DB:
-            sendEventDB(pMsg->getId());
+            sendEventDB(pMsg);
             break;
          case CMD_SET_EVENT_INFO:
             modifyEventTemplate(pMsg);
@@ -1970,80 +1970,29 @@ void ClientSession::deleteAlarmCategory(NXCPMessage *request)
 /**
  * Send event configuration to client
  */
-void ClientSession::sendEventDB(UINT32 dwRqId)
+void ClientSession::sendEventDB(NXCPMessage *pRequest)
 {
    NXCPMessage msg;
    TCHAR szBuffer[4096];
 
    // Prepare response message
    msg.setCode(CMD_REQUEST_COMPLETED);
-   msg.setId(dwRqId);
+   msg.setId(pRequest->getId());
 
    if (checkSysAccessRights(SYSTEM_ACCESS_VIEW_EVENT_DB) || checkSysAccessRights(SYSTEM_ACCESS_EDIT_EVENT_DB) || checkSysAccessRights(SYSTEM_ACCESS_EPP))
    {
       if (!(g_flags & AF_DB_CONNECTION_LOST))
       {
          msg.setField(VID_RCC, RCC_SUCCESS);
-         sendMessage(&msg);
-         msg.deleteAllFields();
-
-         // Prepare data message
-         msg.setCode(CMD_EVENT_DB_RECORD);
-         msg.setId(dwRqId);
-
-         DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
-         DB_UNBUFFERED_RESULT hResult = DBSelectUnbuffered(hdb, _T("SELECT event_code,event_name,severity,flags,message,description FROM event_cfg"));
-         if (hResult != NULL)
-         {
-            while(DBFetch(hResult))
-            {
-               msg.setField(VID_EVENT_CODE, DBGetFieldULong(hResult, 0));
-               msg.setField(VID_NAME, DBGetField(hResult, 1, szBuffer, 1024));
-               msg.setField(VID_SEVERITY, DBGetFieldULong(hResult, 2));
-               msg.setField(VID_FLAGS, DBGetFieldULong(hResult, 3));
-
-               DBGetField(hResult, 4, szBuffer, 4096);
-               msg.setField(VID_MESSAGE, szBuffer);
-
-               DBGetField(hResult, 5, szBuffer, 4096);
-               msg.setField(VID_DESCRIPTION, szBuffer);
-
-               sendMessage(&msg);
-               msg.deleteAllFields();
-            }
-            DBFreeResult(hResult);
-         }
-         DBConnectionPoolReleaseConnection(hdb);
-
-         // End-of-list indicator
-         msg.setField(VID_EVENT_CODE, (UINT32)0);
-                       msg.setEndOfSequence();
-      }
-      else
-      {
-         msg.setField(VID_RCC, RCC_DB_CONNECTION_LOST);
+         GetEventConfiguration(&msg);
       }
    }
    else
-   {
       msg.setField(VID_RCC, RCC_ACCESS_DENIED);
-   }
    sendMessage(&msg);
 }
 
 /**
- * Callback for sending event configuration change notifications
- */
-static void SendEventDBChangeNotification(ClientSession *session, void *arg)
-{
-       if (session->isAuthenticated() &&
-       (session->checkSysAccessRights(SYSTEM_ACCESS_VIEW_EVENT_DB) ||
-        session->checkSysAccessRights(SYSTEM_ACCESS_EDIT_EVENT_DB) ||
-        session->checkSysAccessRights(SYSTEM_ACCESS_EPP)))
-               session->postMessage((NXCPMessage *)arg);
-}
-
-/**
  * Update event template
  */
 void ClientSession::modifyEventTemplate(NXCPMessage *pRequest)
@@ -2053,92 +2002,25 @@ void ClientSession::modifyEventTemplate(NXCPMessage *pRequest)
    // Prepare reply message
    msg.setCode(CMD_REQUEST_COMPLETED);
    msg.setId(pRequest->getId());
-
-   UINT32 eventCode = pRequest->getFieldAsUInt32(VID_EVENT_CODE);
-
    // Check access rights
    if (checkSysAccessRights(SYSTEM_ACCESS_EDIT_EVENT_DB))
    {
-      DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
-
-               bool bEventExist = IsDatabaseRecordExist(hdb, _T("event_cfg"), _T("event_code"), eventCode);
-
-      // Check that we are not trying to create event below 100000
-      if (bEventExist || (eventCode >= FIRST_USER_EVENT_ID))
+      json_t *oldValue, *newValue;
+      UINT32 rcc = UpdateEventObject(pRequest, &msg, &oldValue, &newValue);
+      if (rcc == RCC_SUCCESS)
       {
-         // Prepare and execute SQL query
          TCHAR name[MAX_EVENT_NAME];
          pRequest->getFieldAsString(VID_NAME, name, MAX_EVENT_NAME);
-         if (IsValidObjectName(name, TRUE))
-         {
-            EventTemplate *evt = FindEventTemplateByCode(eventCode);
-            json_t *oldValue = (evt != NULL) ? evt->toJson() : NULL;
-
-            DB_STATEMENT hStmt;
-            if (bEventExist)
-            {
-               hStmt = DBPrepare(hdb, _T("UPDATE event_cfg SET event_name=?,severity=?,flags=?,message=?,description=? WHERE event_code=?"));
-            }
-            else
-            {
-               hStmt = DBPrepare(hdb, _T("INSERT INTO event_cfg (event_name,severity,flags,message,description,event_code,guid) VALUES (?,?,?,?,?,?,?)"));
-            }
-
-            if (hStmt != NULL)
-            {
-               DBBind(hStmt, 1, DB_SQLTYPE_VARCHAR, name, DB_BIND_STATIC);
-               DBBind(hStmt, 2, DB_SQLTYPE_INTEGER, pRequest->getFieldAsInt32(VID_SEVERITY));
-               DBBind(hStmt, 3, DB_SQLTYPE_INTEGER, pRequest->getFieldAsInt32(VID_FLAGS));
-               DBBind(hStmt, 4, DB_SQLTYPE_VARCHAR, pRequest->getFieldAsString(VID_MESSAGE), DB_BIND_DYNAMIC, MAX_EVENT_MSG_LENGTH - 1);
-               DBBind(hStmt, 5, DB_SQLTYPE_TEXT, pRequest->getFieldAsString(VID_DESCRIPTION), DB_BIND_DYNAMIC);
-               DBBind(hStmt, 6, DB_SQLTYPE_INTEGER, eventCode);
-               if (!bEventExist)
-               {
-                  DBBind(hStmt, 7, DB_SQLTYPE_VARCHAR, uuid::generate());
-               }
-
-               if (DBExecute(hStmt))
-               {
-                  msg.setField(VID_RCC, RCC_SUCCESS);
-                  ReloadEvents();
-
-                                          NXCPMessage nmsg(pRequest);
-                                          nmsg.setCode(CMD_EVENT_DB_UPDATE);
-                                          nmsg.setField(VID_NOTIFICATION_CODE, (WORD)NX_NOTIFY_ETMPL_CHANGED);
-                                          EnumerateClientSessions(SendEventDBChangeNotification, &nmsg);
-
-                                          evt = FindEventTemplateByCode(eventCode);
-                                          json_t *newValue = (evt != NULL) ? evt->toJson() : NULL;
-                                          writeAuditLogWithValues(AUDIT_SYSCFG, true, 0, oldValue, newValue, _T("Event template %s [%d] modified"), name, eventCode);
-                                          json_decref(newValue);
-               }
-               else
-               {
-                  msg.setField(VID_RCC, RCC_DB_FAILURE);
-               }
-               DBFreeStatement(hStmt);
-            }
-            else
-            {
-               msg.setField(VID_RCC, RCC_DB_FAILURE);
-            }
-            json_decref(oldValue);
-         }
-         else
-         {
-            msg.setField(VID_RCC, RCC_INVALID_OBJECT_NAME);
-         }
-      }
-      else
-      {
-         msg.setField(VID_RCC, RCC_INVALID_EVENT_CODE);
+         writeAuditLogWithValues(AUDIT_SYSCFG, true, 0, oldValue, newValue, _T("Event template %s [%d] modified"), name, pRequest->getFieldAsUInt32(VID_EVENT_CODE));
+         json_decref(oldValue);
+         json_decref(newValue);
       }
-      DBConnectionPoolReleaseConnection(hdb);
+      msg.setField(VID_RCC, rcc);
    }
    else
    {
       msg.setField(VID_RCC, RCC_ACCESS_DENIED);
-      writeAuditLog(AUDIT_SYSCFG, false, 0, _T("Access denied on modify event template [%d]"), eventCode);
+      writeAuditLog(AUDIT_SYSCFG, false, 0, _T("Access denied on modify event template [%d]"), pRequest->getFieldAsUInt32(VID_EVENT_CODE)); // TODO change message
    }
 
    // Send response
@@ -2162,28 +2044,11 @@ void ClientSession::deleteEventTemplate(NXCPMessage *pRequest)
    // Check access rights
    if (checkSysAccessRights(SYSTEM_ACCESS_EDIT_EVENT_DB) && (dwEventCode >= FIRST_USER_EVENT_ID))
    {
-      DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
-      TCHAR szQuery[256];
-      _sntprintf(szQuery, 256, _T("DELETE FROM event_cfg WHERE event_code=%d"), dwEventCode);
-      if (DBQuery(hdb, szQuery))
-      {
-         DeleteEventTemplateFromList(dwEventCode);
-
-                       NXCPMessage nmsg;
-                       nmsg.setCode(CMD_EVENT_DB_UPDATE);
-                       nmsg.setField(VID_NOTIFICATION_CODE, (WORD)NX_NOTIFY_ETMPL_DELETED);
-                       nmsg.setField(VID_EVENT_CODE, dwEventCode);
-                       EnumerateClientSessions(SendEventDBChangeNotification, &nmsg);
-
-         msg.setField(VID_RCC, RCC_SUCCESS);
-
+      UINT32 rcc = DeleteEventObject(dwEventCode);
+      if (rcc == RCC_SUCCESS)
                        writeAuditLog(AUDIT_SYSCFG, true, 0, _T("Event template [%d] deleted"), dwEventCode);
-      }
-      else
-      {
-         msg.setField(VID_RCC, RCC_DB_FAILURE);
-      }
-      DBConnectionPoolReleaseConnection(hdb);
+
+      msg.setField(VID_RCC, rcc);
    }
    else
    {
index dc63d38..97ecc9a 100644 (file)
@@ -565,7 +565,7 @@ static void SyslogParserCallback(UINT32 eventCode, const TCHAR *eventName, const
 static bool EventNameResolver(const TCHAR *name, UINT32 *code)
 {
        bool success = false;
-       EventTemplate *event = FindEventTemplateByName(name);
+       EventObject *event = FindEventObjectByName(name);
        if (event != NULL)
        {
                *code = event->getCode();
index 23e5a2f..4be43ed 100644 (file)
@@ -531,7 +531,7 @@ private:
    void getAlarmCategories(UINT32 requestId);
    void modifyAlarmCategory(NXCPMessage *pRequest);
    void deleteAlarmCategory(NXCPMessage *pRequest);
-   void sendEventDB(UINT32 dwRqId);
+   void sendEventDB(NXCPMessage *pRequest);
    void modifyEventTemplate(NXCPMessage *pRequest);
    void deleteEventTemplate(NXCPMessage *pRequest);
    void generateEventCode(UINT32 dwRqId);
index decb28e..85c47a4 100644 (file)
 #define EVENTLOG_MAX_MESSAGE_SIZE   255
 #define EVENTLOG_MAX_USERTAG_SIZE   63
 
+class EventObject : public RefCountObject
+{
+protected:
+   UINT32 m_code;
+   TCHAR m_name[MAX_EVENT_NAME];
+   TCHAR *m_description;
+   uuid m_guid;
+
+   EventObject(DB_RESULT hResult, int row);
+   EventObject(NXCPMessage *msg);
+   ~EventObject();
+
+
+public:
+   UINT32 getCode() const { return m_code; }
+   const TCHAR *getName() const { return m_name; }
+   const TCHAR *getDescription() const { return m_description; }
+   const uuid& getGuid() const { return m_guid; }
+
+   virtual void modifyFromMessage(NXCPMessage *msg);
+   virtual void fillMessage(NXCPMessage *msg, UINT32 base) const;
+   virtual bool saveToDatabase() const = 0;
+
+   virtual json_t *toJson() const;
+};
+
 /**
  * Event template
  */
-class EventTemplate : public RefCountObject
+class EventTemplate : public EventObject
 {
 private:
-   UINT32 m_code;
    int m_severity;
-   uuid m_guid;
-   TCHAR m_name[MAX_EVENT_NAME];
    UINT32 m_flags;
    TCHAR *m_messageTemplate;
-   TCHAR *m_description;
 
 protected:
    virtual ~EventTemplate();
 
 public:
    EventTemplate(DB_RESULT hResult, int row);
+   EventTemplate(NXCPMessage *msg);
 
-   UINT32 getCode() const { return m_code; }
    int getSeverity() const { return m_severity; }
-   const uuid& getGuid() const { return m_guid; }
-   const TCHAR *getName() const { return m_name; }
    UINT32 getFlags() const { return m_flags; }
    const TCHAR *getMessageTemplate() const { return m_messageTemplate; }
-   const TCHAR *getDescription() const { return m_description; }
 
-   json_t *toJson() const;
+   virtual void modifyFromMessage(NXCPMessage *msg);
+   virtual void fillMessage(NXCPMessage *msg, UINT32 base) const;
+   virtual bool saveToDatabase() const;
+
+   virtual json_t *toJson() const;
+};
+
+/**
+ * Event group
+ */
+class EventGroup : public EventObject
+{
+private:
+   IntegerArray<UINT32> *m_eventCodeList;
+
+protected:
+   ~EventGroup();
+
+public:
+   EventGroup(DB_RESULT result, int row, IntegerArray<UINT32> *memberCache);
+   EventGroup(NXCPMessage *msg);
+
+   virtual void modifyFromMessage(NXCPMessage *msg);
+   virtual void fillMessage(NXCPMessage *msg, UINT32 base) const;
+   virtual bool saveToDatabase() const;
+
+   UINT32 getMemberCount() { return m_eventCodeList->size(); }
+   UINT32 getMember(int index) { return m_eventCodeList->get(index); }
+   bool isMember(UINT32 eventCode);
+
+   virtual json_t *toJson() const;
 };
 
 /**
@@ -236,14 +285,17 @@ public:
 BOOL InitEventSubsystem();
 void ShutdownEventSubsystem();
 void ReloadEvents();
-void DeleteEventTemplateFromList(UINT32 eventCode);
+UINT32 UpdateEventObject(NXCPMessage *request, NXCPMessage *response, json_t **oldValue, json_t **newValue);
+UINT32 DeleteEventObject(UINT32 eventCode);
+void GetEventConfiguration(NXCPMessage *msg);
+void DeleteEventObjectFromList(UINT32 eventCode);
 void CorrelateEvent(Event *pEvent);
 void CreateNXMPEventRecord(String &str, UINT32 eventCode);
 
 bool EventNameFromCode(UINT32 eventCode, TCHAR *buffer);
 UINT32 NXCORE_EXPORTABLE EventCodeFromName(const TCHAR *name, UINT32 defaultValue = 0);
-EventTemplate *FindEventTemplateByCode(UINT32 eventCode);
-EventTemplate *FindEventTemplateByName(const TCHAR *pszName);
+EventObject *FindEventObjectByCode(UINT32 eventCode);
+EventObject *FindEventObjectByName(const TCHAR *pszName);
 
 bool NXCORE_EXPORTABLE PostEvent(UINT32 eventCode, UINT32 sourceId, const char *format, ...);
 bool NXCORE_EXPORTABLE PostDciEvent(UINT32 eventCode, UINT32 sourceId, UINT32 dciId, const char *format, ...);
index 1c92896..9f7ad96 100644 (file)
@@ -600,6 +600,24 @@ static bool SetSchemaVersion(int version)
 }
 
 /**
+ * Upgrade from V501 to V502
+ */
+static BOOL H_UpgradeFromV501(int currVersion, int newVersion)
+{
+   static const TCHAR *batch =
+            _T("ALTER TABLE event_groups DROP range_start\n")
+            _T("ALTER TABLE event_groups DROP range_end\n")
+            _T("ALTER TABLE event_groups ADD guid varchar(36) null\n")
+            _T("UPDATE event_groups SET guid='04b326c0-5cc0-411f-8587-2836cb87c920' WHERE id=-2147483647\n")
+            _T("UPDATE event_groups SET guid='b61859c6-1768-4a61-a0cf-eed07d688f66' WHERE id=-2147483646\n")
+            _T("<END>");
+   CHK_EXEC(SQLBatch(batch));
+   DBSetNotNullConstraint(g_hCoreDB, _T("event_groups"), _T("guid"));
+   CHK_EXEC(SetSchemaVersion(502));
+   return TRUE;
+}
+
+/**
  * Upgrade from V500 to V501
  */
 static BOOL H_UpgradeFromV500(int currVersion, int newVersion)
@@ -746,6 +764,7 @@ static BOOL H_UpgradeFromV454(int currVersion, int newVersion)
             _T("<END>");
    CHK_EXEC(SQLBatch(batch));
    CHK_EXEC(DBSetNotNullConstraint(g_hCoreDB, _T("interfaces"), _T("parent_iface")));
+
    CHK_EXEC(SetSchemaVersion(455));
    return TRUE;
 }
@@ -11965,6 +11984,7 @@ static struct
    { 458, 459, H_UpgradeFromV458 },
    { 459, 500, H_UpgradeFromV459 },
    { 500, 501, H_UpgradeFromV500 },
+   { 501, 502, H_UpgradeFromV501 },
    { 0, 0, NULL }
 };
 
index 5050d29..a888e95 100644 (file)
@@ -38,6 +38,7 @@ public class SharedIcons
        public static ImageDescriptor CLOSE;
        public static ImageDescriptor COLLAPSE;
        public static ImageDescriptor COLLAPSE_ALL;
+   public static ImageDescriptor CONTAINER;
        public static ImageDescriptor COPY;
        public static ImageDescriptor CSV;
        public static ImageDescriptor CUT;
@@ -77,6 +78,7 @@ public class SharedIcons
        public static Image IMG_CLOSE;
        public static Image IMG_COLLAPSE;
        public static Image IMG_COLLAPSE_ALL;
+   public static Image IMG_CONTAINER;
        public static Image IMG_COPY;
        public static Image IMG_CSV;
        public static Image IMG_CUT;
@@ -121,6 +123,7 @@ public class SharedIcons
                CLOSE = Activator.getImageDescriptor("icons/close.gif"); //$NON-NLS-1$
                COLLAPSE = Activator.getImageDescriptor("icons/collapse.png"); //$NON-NLS-1$
                COLLAPSE_ALL = Activator.getImageDescriptor("icons/collapseall.png"); //$NON-NLS-1$
+      CONTAINER = Activator.getImageDescriptor("icons/container.png"); //$NON-NLS-1$
                COPY = Activator.getImageDescriptor("icons/copy.gif"); //$NON-NLS-1$
                CSV = Activator.getImageDescriptor("icons/csv.png"); //$NON-NLS-1$
                CUT = Activator.getImageDescriptor("icons/cut.gif"); //$NON-NLS-1$
@@ -160,6 +163,7 @@ public class SharedIcons
                IMG_CLOSE = CLOSE.createImage(display);
                IMG_COLLAPSE = COLLAPSE.createImage(display);
                IMG_COLLAPSE_ALL = COLLAPSE_ALL.createImage(display);
+      IMG_CONTAINER = CONTAINER.createImage();
                IMG_COPY = COPY.createImage(display);
                IMG_CSV = CSV.createImage(display);
                IMG_CUT = CUT.createImage(display);
index 2854e3f..5de68b9 100644 (file)
@@ -133,7 +133,7 @@ public class LoginJob implements IRunnableWithProgress
          monitor.setTaskName(Messages.get(display).LoginJob_sync_event_db);
          try
          {
-            session.syncEventTemplates();
+            session.syncEventObjects();
          }
          catch(NXCException e)
          {
index 6cbc244..3825a6e 100644 (file)
@@ -53,7 +53,7 @@ public class ThresholdLabelProvider extends LabelProvider implements ITableLabel
                        case Thresholds.COLUMN_OPERATION:
                                return thresholdIcon;
                        case Thresholds.COLUMN_EVENT:
-                               final EventTemplate event = session.findEventTemplateByCode(((Threshold)element).getFireEvent());
+                               final EventTemplate event = (EventTemplate)session.findEventObjectByCode(((Threshold)element).getFireEvent());
                                return StatusDisplayInfo.getStatusImage((event != null) ? event.getSeverity() : Severity.UNKNOWN);
                }
                return null;
@@ -80,7 +80,7 @@ public class ThresholdLabelProvider extends LabelProvider implements ITableLabel
                                }
                                return text.toString();
                        case Thresholds.COLUMN_EVENT:
-                               final EventTemplate event = session.findEventTemplateByCode(((Threshold)element).getFireEvent());
+                               final EventTemplate event = (EventTemplate)session.findEventObjectByCode(((Threshold)element).getFireEvent());
                                return eventLabelProvider.getText(event);
                }
                return null;
index 06b3e32..6a4ce09 100644 (file)
@@ -51,12 +51,12 @@ public class TableThresholdLabelProvider extends LabelProvider implements ITable
                                return thresholdIcon;
                        case 2:
                        {
-                               final EventTemplate event = session.findEventTemplateByCode(((TableThreshold)element).getActivationEvent());
+                               final EventTemplate event = (EventTemplate)session.findEventObjectByCode(((TableThreshold)element).getActivationEvent());
                                return StatusDisplayInfo.getStatusImage((event != null) ? event.getSeverity() : Severity.UNKNOWN);
                        }
                        case 3:
                        {
-                               final EventTemplate event = session.findEventTemplateByCode(((TableThreshold)element).getDeactivationEvent());
+                               final EventTemplate event = (EventTemplate)session.findEventObjectByCode(((TableThreshold)element).getDeactivationEvent());
                                return StatusDisplayInfo.getStatusImage((event != null) ? event.getSeverity() : Severity.UNKNOWN);
                        }
                }
@@ -77,12 +77,12 @@ public class TableThresholdLabelProvider extends LabelProvider implements ITable
                           return Integer.toString(((TableThreshold)element).getSampleCount());
                        case 2:
                        {
-                               final EventTemplate event = session.findEventTemplateByCode(((TableThreshold)element).getActivationEvent());
+                               final EventTemplate event = (EventTemplate)session.findEventObjectByCode(((TableThreshold)element).getActivationEvent());
                                return eventLabelProvider.getText(event);
                        }
                        case 3:
                        {
-                               final EventTemplate event = session.findEventTemplateByCode(((TableThreshold)element).getDeactivationEvent());
+                               final EventTemplate event = (EventTemplate)session.findEventObjectByCode(((TableThreshold)element).getDeactivationEvent());
                                return eventLabelProvider.getText(event);
                        }
                }
index 0a9ac05..d644203 100644 (file)
@@ -22,7 +22,6 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
-
 import org.eclipse.jface.viewers.ArrayContentProvider;
 import org.eclipse.jface.viewers.ILabelProvider;
 import org.eclipse.jface.viewers.ISelectionChangedListener;
@@ -40,11 +39,11 @@ import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.ui.dialogs.PropertyPage;
-import org.eclipse.ui.model.WorkbenchLabelProvider;
 import org.netxms.client.NXCSession;
+import org.netxms.client.events.EventObject;
 import org.netxms.client.events.EventProcessingPolicyRule;
-import org.netxms.client.events.EventTemplate;
 import org.netxms.ui.eclipse.epp.Messages;
+import org.netxms.ui.eclipse.epp.propertypages.helpers.EventObjectLabelProvider;
 import org.netxms.ui.eclipse.epp.widgets.RuleEditor;
 import org.netxms.ui.eclipse.eventmanager.dialogs.EventSelectionDialog;
 import org.netxms.ui.eclipse.shared.ConsoleSharedData;
@@ -61,7 +60,7 @@ public class RuleEvents extends PropertyPage
        private RuleEditor editor;
        private EventProcessingPolicyRule rule;
        private SortableTableViewer viewer;
-       private Map<Long, EventTemplate> events = new HashMap<Long, EventTemplate>();
+       private Map<Long, EventObject> events = new HashMap<Long, EventObject>();
        private Button addButton;
        private Button deleteButton;
        private Button checkInverted;
@@ -91,7 +90,7 @@ public class RuleEvents extends PropertyPage
       final int[] columnWidths = { 300 };
       viewer = new SortableTableViewer(dialogArea, columnNames, columnWidths, 0, SWT.UP, SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION);
       viewer.setContentProvider(new ArrayContentProvider());
-      viewer.setLabelProvider(new WorkbenchLabelProvider());
+      viewer.setLabelProvider(new EventObjectLabelProvider());
       viewer.setComparator(new ObjectLabelComparator((ILabelProvider)viewer.getLabelProvider()));
       viewer.addSelectionChangedListener(new ISelectionChangedListener() {
                        @Override
@@ -102,8 +101,8 @@ public class RuleEvents extends PropertyPage
                        }
       });
 
-      for(EventTemplate e : session.findMultipleEventTemplates(rule.getEvents().toArray(new Long[0])))
-       events.put(e.getCode(), e);
+      for(EventObject o : session.findMultipleEventObjects(rule.getEvents().toArray(new Long[0])))
+       events.put(o.getCode(), o);
       viewer.setInput(events.values().toArray());
       
       GridData gridData = new GridData();
@@ -172,11 +171,11 @@ public class RuleEvents extends PropertyPage
         */
        private void addEvent()
        {
-               EventSelectionDialog dlg = new EventSelectionDialog(getShell());
+               EventSelectionDialog dlg = new EventSelectionDialog(getShell(), true);
                dlg.enableMultiSelection(true);
                if (dlg.open() == Window.OK)
                {
-                       for(EventTemplate e : dlg.getSelectedEvents())
+                       for(EventObject e : dlg.getSelectedEvents())
                                events.put(e.getCode(), e);
                }
       viewer.setInput(events.values().toArray());
@@ -193,7 +192,7 @@ public class RuleEvents extends PropertyPage
                {
                        while(it.hasNext())
                        {
-                               EventTemplate e = (EventTemplate)it.next();
+                          EventObject e = (EventObject)it.next();
                                events.remove(e.getCode());
                        }
              viewer.setInput(events.values().toArray());
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-package org.netxms.ui.eclipse.eventmanager.views.helpers;
+package org.netxms.ui.eclipse.epp.propertypages.helpers;
 
+import org.eclipse.jface.viewers.ITableColorProvider;
 import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.swt.graphics.Color;
 import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
 import org.eclipse.ui.model.WorkbenchLabelProvider;
-import org.netxms.client.events.EventTemplate;
-import org.netxms.ui.eclipse.console.resources.StatusDisplayInfo;
-import org.netxms.ui.eclipse.eventmanager.views.EventConfigurator;
+import org.netxms.client.events.EventGroup;
+import org.netxms.client.events.EventObject;
+import org.netxms.ui.eclipse.epp.Activator;
 
 /**
  * Label provider for event template objects
  */
-public class EventTemplateLabelProvider extends WorkbenchLabelProvider implements ITableLabelProvider
+public class EventObjectLabelProvider extends WorkbenchLabelProvider implements ITableLabelProvider, ITableColorProvider
 {
+   private static final Color COLOR_GROUP = new Color(Display.getDefault(), new RGB(255, 221, 173));
+   public static Image IMG_EVENT_GROUP = Activator.getImageDescriptor("icons/event_group.png").createImage();
        /* (non-Javadoc)
         * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int)
         */
        @Override
        public Image getColumnImage(Object element, int columnIndex)
        {
-               return (columnIndex == 0) ? getImage(element) : null;
+          if ((columnIndex != 0))
+             return null;
+          if (element instanceof EventGroup)
+             return IMG_EVENT_GROUP;
+               return getImage(element);
        }
 
        /* (non-Javadoc)
@@ -45,21 +55,20 @@ public class EventTemplateLabelProvider extends WorkbenchLabelProvider implement
        @Override
        public String getColumnText(Object element, int columnIndex)
        {
-               switch(columnIndex)
-               {
-                       case EventConfigurator.COLUMN_CODE:
-                               return Long.toString(((EventTemplate)element).getCode());
-                       case EventConfigurator.COLUMN_NAME:
-                               return getText(element);
-                       case EventConfigurator.COLUMN_SEVERITY:
-                               return StatusDisplayInfo.getStatusText(((EventTemplate)element).getSeverity());
-                       case EventConfigurator.COLUMN_FLAGS:
-                               return ((((EventTemplate)element).getFlags() & EventTemplate.FLAG_WRITE_TO_LOG) != 0) ? "L" : "-"; //$NON-NLS-1$ //$NON-NLS-2$
-                       case EventConfigurator.COLUMN_MESSAGE:
-                               return ((EventTemplate)element).getMessage();
-                       case EventConfigurator.COLUMN_DESCRIPTION:
-                               return ((EventTemplate)element).getDescription();
-               }
-               return null;
+          return ((EventObject)element).getName();     
        }
+
+   @Override
+   public Color getForeground(Object element, int columnIndex)
+   {
+      return null;
+   }
+
+   @Override
+   public Color getBackground(Object element, int columnIndex)
+   {
+      if (element instanceof EventGroup)
+         return COLOR_GROUP;
+      return null;
+   }
 }
index 72f1712..7f18f08 100644 (file)
@@ -62,6 +62,7 @@ import org.netxms.client.ServerAction;
 import org.netxms.client.SessionListener;
 import org.netxms.client.SessionNotification;
 import org.netxms.client.events.AlarmCategory;
+import org.netxms.client.events.EventObject;
 import org.netxms.client.events.EventProcessingPolicy;
 import org.netxms.client.events.EventProcessingPolicyRule;
 import org.netxms.client.events.EventTemplate;
@@ -1266,8 +1267,8 @@ public class EventProcessingPolicyEditor extends ViewPart implements ISaveablePa
       // check event names
       for(Long code : rule.getEvents())
       {
-         EventTemplate evt = session.findEventTemplateByCode(code);
-         if ((evt != null) && evt.getName().toLowerCase().contains(filterText))
+         EventObject evo = session.findEventObjectByCode(code);
+         if ((evo != null) && evo.getName().toLowerCase().contains(filterText))
             return true;
       }
       
index 01eb157..4d457e2 100644 (file)
@@ -66,6 +66,7 @@ import org.netxms.client.NXCSession;
 import org.netxms.client.ServerAction;
 import org.netxms.client.constants.Severity;
 import org.netxms.client.events.AlarmCategory;
+import org.netxms.client.events.EventObject;
 import org.netxms.client.events.EventProcessingPolicyRule;
 import org.netxms.client.events.EventTemplate;
 import org.netxms.client.objects.AbstractObject;
@@ -538,32 +539,35 @@ public class RuleEditor extends Composite
          final MouseListener listener = createMouseListener("org.netxms.ui.eclipse.epp.propertypages.RuleEvents#10"); //$NON-NLS-1$
          addConditionGroupLabel(clientArea, Messages.get().RuleEditor_EventIs, needAnd, rule.isEventsInverted(), listener);
 
-         List<EventTemplate> sortedEvents = new ArrayList<EventTemplate>(rule.getEvents().size());
+         List<EventObject> sortedEvents = new ArrayList<EventObject>(rule.getEvents().size());
          for(Long code : rule.getEvents())
          {
-            EventTemplate event = session.findEventTemplateByCode(code);
+            EventObject event = session.findEventObjectByCode(code);
             if (event == null)
             {
                event = new EventTemplate(code);
-               event.setSeverity(Severity.UNKNOWN);
+               ((EventTemplate)event).setSeverity(Severity.UNKNOWN);
                event.setName("<" + code.toString() + ">"); //$NON-NLS-1$ //$NON-NLS-2$
             }
             sortedEvents.add(event);
          }
-         Collections.sort(sortedEvents, new Comparator<EventTemplate>() {
+         Collections.sort(sortedEvents, new Comparator<EventObject>() {
             @Override
-            public int compare(EventTemplate t1, EventTemplate t2)
+            public int compare(EventObject t1, EventObject t2)
             {
                return t1.getName().compareToIgnoreCase(t2.getName());
             }
          });
 
-         for(EventTemplate e : sortedEvents)
+         for(EventObject e : sortedEvents)
          {
             CLabel clabel = createCLabel(clientArea, 2, false);
             clabel.addMouseListener(listener);
             clabel.setText(e.getName());
-            clabel.setImage(StatusDisplayInfo.getStatusImage(e.getSeverity()));
+            if (e instanceof EventTemplate)
+               clabel.setImage(StatusDisplayInfo.getStatusImage(((EventTemplate)e).getSeverity()));
+            else
+               clabel.setImage(SharedIcons.IMG_CONTAINER);
          }
          needAnd = true;
       }
diff --git a/webui/webapp/EventManager/src/org/netxms/ui/eclipse/eventmanager/dialogs/EditEventGroupDialog.java b/webui/webapp/EventManager/src/org/netxms/ui/eclipse/eventmanager/dialogs/EditEventGroupDialog.java
new file mode 100644 (file)
index 0000000..60a9a70
--- /dev/null
@@ -0,0 +1,105 @@
+/**
+ * NetXMS - open source network management system
+ * Copyright (C) 2003-2017 Raden Solutions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.netxms.ui.eclipse.eventmanager.dialogs;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.netxms.client.events.EventGroup;
+import org.netxms.ui.eclipse.tools.WidgetHelper;
+import org.netxms.ui.eclipse.widgets.LabeledText;
+
+public class EditEventGroupDialog  extends Dialog
+{
+   private LabeledText name;
+   private LabeledText description;
+   private EventGroup group;
+
+   public EditEventGroupDialog(Shell parentShell, EventGroup group)
+   {
+      super(parentShell);
+      this.group = group;
+   }
+
+   /* (non-Javadoc)
+    * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
+    */
+   @Override
+   protected Control createDialogArea(Composite parent)
+   {
+      Composite dialogArea = (Composite)super.createDialogArea(parent);
+
+      GridLayout layout = new GridLayout();
+      layout.marginWidth = WidgetHelper.DIALOG_WIDTH_MARGIN;
+      layout.marginHeight = WidgetHelper.DIALOG_HEIGHT_MARGIN;
+      layout.horizontalSpacing = WidgetHelper.OUTER_SPACING * 2;
+      dialogArea.setLayout(layout);
+            
+      GridData gd = new GridData();
+      gd.horizontalAlignment = SWT.FILL;
+      
+      name = new LabeledText(dialogArea, SWT.NONE);
+      name.setLabel("Name");
+      name.setText(group.getName());
+      name.getTextControl().setTextLimit(63);
+      gd = new GridData();
+      gd.grabExcessHorizontalSpace = true;
+      gd.horizontalAlignment = SWT.FILL;
+      name.setLayoutData(gd);
+      
+      description = new LabeledText(dialogArea, SWT.NONE, SWT.MULTI | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.WRAP);
+      description.setLabel("Description");
+      description.setText(group.getDescription());
+      description.getTextControl().setTextLimit(254);
+      gd = new GridData();
+      gd.grabExcessHorizontalSpace = true;
+      gd.horizontalAlignment = SWT.FILL;
+      gd.heightHint = 200;
+      gd.widthHint = 450;
+      gd.verticalAlignment = SWT.FILL;
+      description.setLayoutData(gd);
+
+      return dialogArea;
+   }
+
+   /* (non-Javadoc)
+    * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
+    */
+   @Override
+   protected void configureShell(Shell newShell)
+   {
+      super.configureShell(newShell);
+      newShell.setText("Create event group");
+   }
+
+   /* (non-Javadoc)
+    * @see org.eclipse.jface.dialogs.Dialog#okPressed()
+    */
+   @Override
+   protected void okPressed()
+   {
+      group.setName(name.getText());
+      group.setDescription(description.getText());
+      super.okPressed();
+   }
+}
index 2f9ba8f..d414a07 100644 (file)
@@ -21,30 +21,20 @@ package org.netxms.ui.eclipse.eventmanager.dialogs;
 import java.util.List;
 import org.eclipse.jface.dialogs.Dialog;
 import org.eclipse.jface.dialogs.IDialogSettings;
-import org.eclipse.jface.viewers.ArrayContentProvider;
 import org.eclipse.jface.viewers.DoubleClickEvent;
 import org.eclipse.jface.viewers.IDoubleClickListener;
 import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.TableViewer;
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Shell;
-import org.netxms.client.events.EventTemplate;
+import org.netxms.client.events.EventObject;
 import org.netxms.ui.eclipse.eventmanager.Activator;
 import org.netxms.ui.eclipse.eventmanager.Messages;
-import org.netxms.ui.eclipse.eventmanager.dialogs.helpers.EventListFilter;
-import org.netxms.ui.eclipse.eventmanager.views.helpers.EventTemplateComparator;
-import org.netxms.ui.eclipse.eventmanager.views.helpers.EventTemplateLabelProvider;
-import org.netxms.ui.eclipse.shared.ConsoleSharedData;
-import org.netxms.ui.eclipse.tools.WidgetHelper;
-import org.netxms.ui.eclipse.widgets.FilterText;
-import org.netxms.ui.eclipse.widgets.SortableTableViewer;
+import org.netxms.ui.eclipse.eventmanager.widgets.EventObjectList;
 
 /**
  * Event selection dialog
@@ -52,20 +42,22 @@ import org.netxms.ui.eclipse.widgets.SortableTableViewer;
  */
 public class EventSelectionDialog extends Dialog
 {
+   private static final String TABLE_CONFIG_PREFIX = "SelectEvent"; //$NON-NLS-1$
+   
        private boolean multiSelection;
-       private FilterText filterText;
-       private TableViewer eventList;
-       private EventTemplate selectedEvents[];
-       private EventListFilter filter;
+   private boolean showGroups;
+       private EventObject selectedEvents[];
+       private EventObjectList eventObjectList;
 
        /**
         * @param parentShell
         */
-       public EventSelectionDialog(Shell parentShell)
+       public EventSelectionDialog(Shell parentShell, boolean showGroups)
        {
                super(parentShell);
                setShellStyle(getShellStyle() | SWT.RESIZE);
                multiSelection = false;
+               this.showGroups = showGroups;
        }
 
        /* (non-Javadoc)
@@ -79,7 +71,7 @@ public class EventSelectionDialog extends Dialog
                IDialogSettings settings = Activator.getDefault().getDialogSettings();
                try
                {
-                       newShell.setSize(settings.getInt("SelectEvent.cx"), settings.getInt("SelectEvent.cy")); //$NON-NLS-1$ //$NON-NLS-2$
+                       newShell.setSize(settings.getInt(TABLE_CONFIG_PREFIX + ".cx"), settings.getInt(TABLE_CONFIG_PREFIX + ".cy")); //$NON-NLS-1$ //$NON-NLS-2$
                }
                catch(NumberFormatException e)
                {
@@ -92,56 +84,19 @@ public class EventSelectionDialog extends Dialog
        @Override
        protected Control createDialogArea(Composite parent)
        {
-               IDialogSettings settings = Activator.getDefault().getDialogSettings();
                Composite dialogArea = (Composite)super.createDialogArea(parent);
                
-               GridLayout layout = new GridLayout();
-      layout.marginWidth = WidgetHelper.DIALOG_WIDTH_MARGIN;
-      layout.marginHeight = WidgetHelper.DIALOG_HEIGHT_MARGIN;
-      layout.horizontalSpacing = WidgetHelper.OUTER_SPACING;
-               layout.numColumns = 2;
-               dialogArea.setLayout(layout);
-               
-               filterText = new FilterText(dialogArea, SWT.NONE, null, false);
-               GridData gd = new GridData();
-               gd.grabExcessHorizontalSpace = true;
-               gd.horizontalAlignment = SWT.FILL;
-               filterText.setLayoutData(gd);
-               final String filterString = settings.get("SelectEvent.Filter"); //$NON-NLS-1$
-               if (filterString != null)
-                       filterText.setText(filterString);
-               
-               final String[] names = { Messages.get().EventSelectionDialog_Code, Messages.get().EventSelectionDialog_Name };
-               final int[] widths = { 80, 350 };
-               eventList = new SortableTableViewer(dialogArea, names, widths, 1, SWT.UP, 
-                               SWT.BORDER | SWT.FULL_SELECTION | (multiSelection ? SWT.MULTI : SWT.SINGLE) | SWT.H_SCROLL | SWT.V_SCROLL);
-               eventList.setContentProvider(new ArrayContentProvider());
-               eventList.setComparator(new EventTemplateComparator());
-               eventList.setLabelProvider(new EventTemplateLabelProvider());
-               filter = new EventListFilter();
-               if (filterString != null)
-                       filter.setFilterString(filterString);
-               eventList.addFilter(filter);
-               eventList.setInput(ConsoleSharedData.getSession().getCachedEventTemplates());
-               gd = new GridData();
-               gd.grabExcessHorizontalSpace = true;
-               gd.horizontalAlignment = SWT.FILL;
-               gd.horizontalSpan = 2;
-               gd.verticalAlignment = SWT.FILL;
-               gd.grabExcessVerticalSpace = true;
-               gd.heightHint = 350;
-               eventList.getTable().setLayoutData(gd);
+               dialogArea.setLayout(new FormLayout());
                
-               filterText.addModifyListener(new ModifyListener() {
-                       @Override
-                       public void modifyText(ModifyEvent e)
-                       {
-                               filter.setFilterString(filterText.getText());
-                               eventList.refresh();
-                       }
-               });
+               eventObjectList = new EventObjectList(dialogArea, SWT.NONE, TABLE_CONFIG_PREFIX, true, showGroups);
+               FormData fd = new FormData();
+      fd.left = new FormAttachment(0, 0);
+      fd.top = new FormAttachment(100, 0);
+      fd.right = new FormAttachment(100, 0);
+      fd.bottom = new FormAttachment(100, 0);
+      eventObjectList.setLayoutData(fd);
                
-               eventList.addDoubleClickListener(new IDoubleClickListener() {
+      eventObjectList.getViewer().addDoubleClickListener(new IDoubleClickListener() {
                        @Override
                        public void doubleClick(DoubleClickEvent event)
                        {
@@ -149,46 +104,21 @@ public class EventSelectionDialog extends Dialog
                        }
                });
                
-               filterText.setFocus();
                return dialogArea;
        }
        
        /* (non-Javadoc)
-        * @see org.eclipse.jface.dialogs.Dialog#cancelPressed()
-        */
-       @Override
-       protected void cancelPressed()
-       {
-               saveSettings();
-               super.cancelPressed();
-       }
-
-       /* (non-Javadoc)
         * @see org.eclipse.jface.dialogs.Dialog#okPressed()
         */
        @SuppressWarnings("unchecked")
        @Override
        protected void okPressed()
        {
-               final IStructuredSelection selection = (IStructuredSelection)eventList.getSelection();
-               final List<EventTemplate> list = selection.toList();
-               selectedEvents = list.toArray(new EventTemplate[list.size()]);
-               saveSettings();
+               final IStructuredSelection selection = (IStructuredSelection)eventObjectList.getViewer().getSelection();
+               final List<EventObject> list = selection.toList();
+               selectedEvents = list.toArray(new EventObject[list.size()]);
                super.okPressed();
        }
-       
-       /**
-        * Save dialog settings
-        */
-       private void saveSettings()
-       {
-               Point size = getShell().getSize();
-               IDialogSettings settings = Activator.getDefault().getDialogSettings();
-
-               settings.put("SelectEvent.cx", size.x); //$NON-NLS-1$
-               settings.put("SelectEvent.cy", size.y); //$NON-NLS-1$
-               settings.put("SelectEvent.Filter", filterText.getText()); //$NON-NLS-1$
-       }
 
        /**
         * @return true if multiple event selection is enabled
@@ -213,7 +143,7 @@ public class EventSelectionDialog extends Dialog
         * 
         * @return Selected event templates
         */
-       public EventTemplate[] getSelectedEvents()
+       public EventObject[] getSelectedEvents()
        {
                return selectedEvents;
        }
index 0394b33..677140a 100644 (file)
@@ -20,7 +20,7 @@ package org.netxms.ui.eclipse.eventmanager.dialogs.helpers;
 
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.jface.viewers.ViewerFilter;
-import org.netxms.client.events.EventTemplate;
+import org.netxms.client.events.EventObject;
 
 /**
  * Filter for event list
@@ -39,7 +39,7 @@ public class EventListFilter extends ViewerFilter
                if (filterString == null)
                        return true;
                
-               return ((EventTemplate)element).getName().toLowerCase().contains(filterString);
+               return ((EventObject)element).getName().toLowerCase().contains(filterString);
        }
 
        /**
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-package org.netxms.ui.eclipse.eventmanager.views.helpers;
+package org.netxms.ui.eclipse.eventmanager.dialogs.helpers;
 
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.jface.viewers.ViewerComparator;
 import org.eclipse.swt.SWT;
-import org.netxms.client.events.EventTemplate;
-import org.netxms.ui.eclipse.eventmanager.views.EventConfigurator;
+import org.netxms.client.events.EventObject;
+import org.netxms.ui.eclipse.eventmanager.widgets.EventObjectList;
 import org.netxms.ui.eclipse.widgets.SortableTableViewer;
 
 /**
  * Event template comparator
  */
-public class EventTemplateComparator extends ViewerComparator
+public class EventObjectComparator extends ViewerComparator
 {
        /* (non-Javadoc)
         * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
@@ -40,23 +40,11 @@ public class EventTemplateComparator extends ViewerComparator
 
                switch((Integer)((SortableTableViewer)viewer).getTable().getSortColumn().getData("ID")) //$NON-NLS-1$
                {
-                       case EventConfigurator.COLUMN_CODE:
-                               result = (int)(((EventTemplate)e1).getCode() - ((EventTemplate)e2).getCode());
+                       case EventObjectList.COLUMN_CODE:
+                               result = (int)(((EventObject)e1).getCode() - ((EventObject)e2).getCode());
                                break;
-                       case EventConfigurator.COLUMN_NAME:
-                               result = ((EventTemplate)e1).getName().compareToIgnoreCase(((EventTemplate)e2).getName());
-                               break;
-                       case EventConfigurator.COLUMN_SEVERITY:
-                               result = ((EventTemplate)e1).getSeverity().compareTo(((EventTemplate)e2).getSeverity());
-                               break;
-                       case EventConfigurator.COLUMN_FLAGS:
-                               result = ((EventTemplate)e1).getFlags() - ((EventTemplate)e2).getFlags();
-                               break;
-                       case EventConfigurator.COLUMN_MESSAGE:
-                               result = ((EventTemplate)e1).getMessage().compareToIgnoreCase(((EventTemplate)e2).getMessage());
-                               break;
-                       case EventConfigurator.COLUMN_DESCRIPTION:
-                               result = ((EventTemplate)e1).getDescription().compareToIgnoreCase(((EventTemplate)e2).getDescription());
+                       case EventObjectList.COLUMN_NAME:
+                               result = ((EventObject)e1).getName().compareToIgnoreCase(((EventObject)e2).getName());
                                break;
                        default:
                                result = 0;
index 18bd8ad..b529c74 100644 (file)
  */
 package org.netxms.ui.eclipse.eventmanager.views;
 
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.jface.action.Action;
 import org.eclipse.jface.action.GroupMarker;
-import org.eclipse.jface.action.IMenuListener;
 import org.eclipse.jface.action.IMenuManager;
 import org.eclipse.jface.action.IToolBarManager;
-import org.eclipse.jface.action.MenuManager;
 import org.eclipse.jface.action.Separator;
-import org.eclipse.jface.commands.ActionHandler;
-import org.eclipse.jface.dialogs.IDialogSettings;
-import org.eclipse.jface.viewers.ArrayContentProvider;
 import org.eclipse.jface.viewers.DoubleClickEvent;
 import org.eclipse.jface.viewers.IDoubleClickListener;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.jface.window.Window;
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
 import org.eclipse.swt.layout.FormAttachment;
 import org.eclipse.swt.layout.FormData;
 import org.eclipse.swt.layout.FormLayout;
 import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Menu;
-import org.eclipse.swt.widgets.Shell;
 import org.eclipse.ui.IActionBars;
-import org.eclipse.ui.IViewSite;
 import org.eclipse.ui.IWorkbenchActionConstants;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.contexts.IContextService;
-import org.eclipse.ui.handlers.IHandlerService;
 import org.eclipse.ui.part.ViewPart;
-import org.netxms.client.NXCSession;
-import org.netxms.client.SessionListener;
-import org.netxms.client.SessionNotification;
-import org.netxms.client.events.EventTemplate;
-import org.netxms.ui.eclipse.actions.RefreshAction;
-import org.netxms.ui.eclipse.console.resources.SharedIcons;
-import org.netxms.ui.eclipse.eventmanager.Activator;
-import org.netxms.ui.eclipse.eventmanager.Messages;
-import org.netxms.ui.eclipse.eventmanager.dialogs.EditEventTemplateDialog;
-import org.netxms.ui.eclipse.eventmanager.views.helpers.EventTemplateComparator;
-import org.netxms.ui.eclipse.eventmanager.views.helpers.EventTemplateFilter;
-import org.netxms.ui.eclipse.eventmanager.views.helpers.EventTemplateLabelProvider;
-import org.netxms.ui.eclipse.jobs.ConsoleJob;
-import org.netxms.ui.eclipse.shared.ConsoleSharedData;
-import org.netxms.ui.eclipse.tools.MessageDialogHelper;
-import org.netxms.ui.eclipse.tools.WidgetHelper;
-import org.netxms.ui.eclipse.widgets.FilterText;
-import org.netxms.ui.eclipse.widgets.SortableTableViewer;
+import org.netxms.ui.eclipse.eventmanager.widgets.EventObjectList;
 
 /**
  * Event configuration view
  * 
  */
-public class EventConfigurator extends ViewPart implements SessionListener
+public class EventConfigurator extends ViewPart
 {
        public static final String ID = "org.netxms.ui.eclipse.eventmanager.view.event_configurator"; //$NON-NLS-1$
        public static final String JOB_FAMILY = "EventConfiguratorJob"; //$NON-NLS-1$
-
-       private static final String TABLE_CONFIG_PREFIX = "EventTemplateList"; //$NON-NLS-1$
        
-       // Columns
-       public static final int COLUMN_CODE = 0;
-       public static final int COLUMN_NAME = 1;
-       public static final int COLUMN_SEVERITY = 2;
-       public static final int COLUMN_FLAGS = 3;
-       public static final int COLUMN_MESSAGE = 4;
-       public static final int COLUMN_DESCRIPTION = 5;
-
-       private HashMap<Long, EventTemplate> eventTemplates;
-       private SortableTableViewer viewer;
-   private FilterText filterControl;
-       private Action actionNew;
-       private Action actionEdit;
-       private Action actionDelete;
-   private Action actionShowFilter;
-       private Action actionRefresh;
-       private NXCSession session;
-       private EventTemplateFilter filter;
-       private boolean filterEnabled;
-
-       /* (non-Javadoc)
-        * @see org.eclipse.ui.part.ViewPart#init(org.eclipse.ui.IViewSite)
-        */
-       @Override
-   public void init(IViewSite site) throws PartInitException
-   {
-      super.init(site);
+   private static final String TABLE_CONFIG_PREFIX = "EventTemplateList"; //$NON-NLS-1$
 
-      IDialogSettings settings = Activator.getDefault().getDialogSettings();
-      filterEnabled = settings.getBoolean("EventConfigurator.filterEnabled"); //$NON-NLS-1$
-   }
+       private EventObjectList dataView;
 
    /* (non-Javadoc)
         * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
         */
        @Override
        public void createPartControl(Composite parent)
-       {
-               session = (NXCSession)ConsoleSharedData.getSession();
-               
+       {               
       parent.setLayout(new FormLayout());
       
-      // Create filter area
-      filterControl = new FilterText(parent, SWT.NONE);
-      filterControl.addModifyListener(new ModifyListener() {
-         @Override
-         public void modifyText(ModifyEvent e)
-         {
-            onFilterModify();
-         }
-      });
-      filterControl.setCloseAction(new Action() {
-         @Override
-         public void run()
-         {
-            enableFilter(false);
-         }
-      });
-               
-               final String[] names = { Messages.get().EventConfigurator_ColCode, Messages.get().EventConfigurator_ColName, Messages.get().EventConfigurator_ColSeverity, Messages.get().EventConfigurator_ColFlags, Messages.get().EventConfigurator_ColMessage, Messages.get().EventConfigurator_ColDescription };
-               final int[] widths = { 70, 200, 90, 50, 400, 400 };
-               viewer = new SortableTableViewer(parent, names, widths, 0, SWT.UP, SortableTableViewer.DEFAULT_STYLE);
-               WidgetHelper.restoreTableViewerSettings(viewer, Activator.getDefault().getDialogSettings(), TABLE_CONFIG_PREFIX);
-               viewer.setContentProvider(new ArrayContentProvider());
-               viewer.setLabelProvider(new EventTemplateLabelProvider());
-               viewer.setComparator(new EventTemplateComparator());
-               filter = new EventTemplateFilter();
-               viewer.addFilter(filter);
-               viewer.addSelectionChangedListener(new ISelectionChangedListener()
-               {
-                       @Override
-                       public void selectionChanged(SelectionChangedEvent event)
-                       {
-                               IStructuredSelection selection = (IStructuredSelection)event.getSelection();
-                               if (selection != null)
-                               {
-                                       actionEdit.setEnabled(selection.size() == 1);
-                                       actionDelete.setEnabled(selection.size() > 0);
-                               }
-                       }
-               });
-               viewer.addDoubleClickListener(new IDoubleClickListener() {
-                       @Override
-                       public void doubleClick(DoubleClickEvent event)
-                       {
-                               actionEdit.run();
-                       }
-               });
-               viewer.getTable().addDisposeListener(new DisposeListener() {
-                       @Override
-                       public void widgetDisposed(DisposeEvent e)
-                       {
-                               WidgetHelper.saveTableViewerSettings(viewer, Activator.getDefault().getDialogSettings(), TABLE_CONFIG_PREFIX);
-                       }
-               });
-               
-      // Setup layout
+      dataView = new EventObjectList(this, parent, SWT.NONE, TABLE_CONFIG_PREFIX);
       FormData fd = new FormData();
       fd.left = new FormAttachment(0, 0);
-      fd.top = new FormAttachment(filterControl);
+      fd.top = new FormAttachment(100, 0);
       fd.right = new FormAttachment(100, 0);
       fd.bottom = new FormAttachment(100, 0);
-      viewer.getControl().setLayoutData(fd);
+      dataView.setLayoutData(fd);
       
-      fd = new FormData();
-      fd.left = new FormAttachment(0, 0);
-      fd.top = new FormAttachment(0, 0);
-      fd.right = new FormAttachment(100, 0);
-      filterControl.setLayoutData(fd);
-               
-      activateContext();
-               createActions();
-               contributeToActionBars();
-               createPopupMenu();
-
-               refreshView();
-               session.addListener(this);
-
-      // Set initial focus to filter input line
-      if (filterEnabled)
-         filterControl.setFocus();
-      else
-         enableFilter(false); // Will hide filter area correctly
-       }
-
-       /**
-        * Refresh view
-        */
-       private void refreshView()
-       {
-               new ConsoleJob(Messages.get().EventConfigurator_OpenJob_Title, this, Activator.PLUGIN_ID, JOB_FAMILY) {
+               dataView.getViewer().addDoubleClickListener(new IDoubleClickListener() {
                        @Override
-                       protected String getErrorMessage()
-                       {
-                               return Messages.get().EventConfigurator_OpenJob_Error;
-                       }
-
-                       @Override
-                       protected void runInternal(IProgressMonitor monitor) throws Exception
+                       public void doubleClick(DoubleClickEvent event)
                        {
-                               final List<EventTemplate> list = session.getEventTemplates();
-                               runInUIThread(new Runnable() {
-                                       @Override
-                                       public void run()
-                                       {
-                                               eventTemplates = new HashMap<Long, EventTemplate>(list.size());
-                                               for(final EventTemplate t: list)
-                                               {
-                                                       eventTemplates.put(t.getCode(), t);
-                                               }
-                                               viewer.setInput(eventTemplates.values().toArray());
-                                       }
-                               });
+                          dataView.getActionEdit().run();
                        }
-               }.start();
-       }
-
-       /**
-        * Process client session notifications
-        */
-       @Override
-       public void notificationHandler(final SessionNotification n)
-       {
-               switch(n.getCode())
-               {
-                       case SessionNotification.EVENT_TEMPLATE_MODIFIED:
-                               viewer.getControl().getDisplay().asyncExec(new Runnable() {
-                                       @Override
-                                       public void run()
-                                       {
-                                               EventTemplate oldTmpl = eventTemplates.get(n.getSubCode());
-                                               if (oldTmpl != null)
-                                               {
-                                                       oldTmpl.setAll((EventTemplate)n.getObject());
-                                                       viewer.update(oldTmpl, null);
-                                               }
-                                               else
-                                               {
-                                                       eventTemplates.put(n.getSubCode(), (EventTemplate)n.getObject());
-                                                       viewer.setInput(eventTemplates.values().toArray());
-                                               }
-                                       }
-                               });
-                               break;
-                       case SessionNotification.EVENT_TEMPLATE_DELETED:
-                               viewer.getControl().getDisplay().asyncExec(new Runnable() {
-                                       @Override
-                                       public void run()
-                                       {
-                                               eventTemplates.remove(n.getSubCode());
-                                               viewer.setInput(eventTemplates.values().toArray());
-                                       }
-                               });
-                               break;
-               }
+               });
+               
+               contributeToActionBars();
        }
 
-   /**
-    * Activate context
-    */
-   private void activateContext()
-   {
-      IContextService contextService = (IContextService)getSite().getService(IContextService.class);
-      if (contextService != null)
-      {
-         contextService.activateContext("org.netxms.ui.eclipse.eventmanager.contexts.EventConfigurator"); //$NON-NLS-1$
-      }
-   }
-
        /**
         * Contribute actions to action bar
         */
@@ -314,11 +92,12 @@ public class EventConfigurator extends ViewPart implements SessionListener
         */
        private void fillLocalPullDown(IMenuManager manager)
        {
-               manager.add(actionNew);
+               manager.add(dataView.getActionNewTemplate());
                manager.add(new Separator());
-      manager.add(actionShowFilter);
+      manager.add(dataView.getActionShowFilter());
       manager.add(new Separator());
-               manager.add(actionRefresh);
+      manager.add(dataView.getActionShowGroups());
+               manager.add(dataView.getActionRefresh());
        }
 
        /**
@@ -329,89 +108,10 @@ public class EventConfigurator extends ViewPart implements SessionListener
         */
        private void fillLocalToolBar(IToolBarManager manager)
        {
-               manager.add(actionNew);
-      manager.add(actionShowFilter);
+               manager.add(dataView.getActionNewTemplate());
+      manager.add(dataView.getActionShowFilter());
                manager.add(new Separator());
-               manager.add(actionRefresh);
-       }
-
-       /**
-        * Create actions
-        */
-       private void createActions()
-       {
-      final IHandlerService handlerService = (IHandlerService)getSite().getService(IHandlerService.class);
-      
-               actionRefresh = new RefreshAction(this) {
-                       @Override
-                       public void run()
-                       {
-                               refreshView();
-                       }
-               };
-
-               actionNew = new Action(Messages.get().EventConfigurator_NewEvent, SharedIcons.ADD_OBJECT) {
-                       @Override
-                       public void run()
-                       {
-                               createNewEventTemplate();
-                       }
-               };
-               actionNew.setActionDefinitionId("org.netxms.ui.eclipse.eventmanager.commands.new_event_template"); //$NON-NLS-1$
-      handlerService.activateHandler(actionNew.getActionDefinitionId(), new ActionHandler(actionNew));
-
-               actionEdit = new Action(Messages.get().EventConfigurator_Properties, SharedIcons.EDIT) { //$NON-NLS-1$
-                       @Override
-                       public void run()
-                       {
-                               editEventTemplate();
-                       }
-               };
-               actionEdit.setEnabled(false);
-
-               actionDelete = new Action(Messages.get().EventConfigurator_Delete, SharedIcons.DELETE_OBJECT) {
-                       @Override
-                       public void run()
-                       {
-                               deleteEventTemplate();
-                       }
-               };
-               actionDelete.setEnabled(false);
-
-      actionShowFilter = new Action(Messages.get().EventConfigurator_ShowFilter, Action.AS_CHECK_BOX) {
-         @Override
-         public void run()
-         {
-            enableFilter(actionShowFilter.isChecked());
-         }
-      };
-      actionShowFilter.setImageDescriptor(SharedIcons.FILTER);
-      actionShowFilter.setChecked(filterEnabled);
-      actionShowFilter.setActionDefinitionId("org.netxms.ui.eclipse.eventmanager.commands.show_filter"); //$NON-NLS-1$
-      handlerService.activateHandler(actionShowFilter.getActionDefinitionId(), new ActionHandler(actionShowFilter));
-       }
-
-       /**
-        * Create pop-up menu
-        */
-       private void createPopupMenu()
-       {
-               // Create menu manager.
-               MenuManager menuMgr = new MenuManager();
-               menuMgr.setRemoveAllWhenShown(true);
-               menuMgr.addMenuListener(new IMenuListener() {
-                       public void menuAboutToShow(IMenuManager mgr)
-                       {
-                               fillContextMenu(mgr);
-                       }
-               });
-
-               // Create menu.
-               Menu menu = menuMgr.createContextMenu(viewer.getControl());
-               viewer.getControl().setMenu(menu);
-
-               // Register menu for extension.
-               getSite().registerContextMenu(menuMgr, viewer);
+               manager.add(dataView.getActionRefresh());
        }
 
        /**
@@ -422,10 +122,13 @@ public class EventConfigurator extends ViewPart implements SessionListener
        protected void fillContextMenu(final IMenuManager mgr)
        {
                mgr.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
-               mgr.add(actionNew);
-               mgr.add(actionDelete);
+               mgr.add(dataView.getActionRefresh());
+               mgr.add(dataView.getActionDelete());
+      mgr.add(dataView.getActionNewGroup());
+               mgr.add(dataView.getActionRemoveFromGroup());
                mgr.add(new Separator());
-               mgr.add(actionEdit);
+               mgr.add(dataView.getActionShowGroups());
+               mgr.add(dataView.getActionEdit());
        }
 
        /* (non-Javadoc)
@@ -434,160 +137,6 @@ public class EventConfigurator extends ViewPart implements SessionListener
        @Override
        public void setFocus()
        {
-               viewer.getControl().setFocus();
-       }
-
-       /**
-        * Create new event template
-        */
-       protected void createNewEventTemplate()
-       {
-               final EventTemplate etmpl = new EventTemplate(0);
-               EditEventTemplateDialog dlg = new EditEventTemplateDialog(getSite().getShell(), etmpl, false);