]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.workbench/src/org/simantics/workbench/internal/contributions/GraphRequestStatusTrim.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.workbench / src / org / simantics / workbench / internal / contributions / GraphRequestStatusTrim.java
index 5531c32ae607121aa52c18ab7363066461e9db55..868c87b99337e43acfab39577a08188a6b11c4d2 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.workbench.internal.contributions;\r
-\r
-import org.eclipse.jface.action.Action;\r
-import org.eclipse.jface.action.IMenuListener;\r
-import org.eclipse.jface.action.IMenuManager;\r
-import org.eclipse.jface.action.MenuManager;\r
-import org.eclipse.jface.preference.IPreferenceStore;\r
-import org.eclipse.jface.util.IPropertyChangeListener;\r
-import org.eclipse.jface.util.PropertyChangeEvent;\r
-import org.eclipse.osgi.util.NLS;\r
-import org.eclipse.swt.SWT;\r
-import org.eclipse.swt.graphics.Color;\r
-import org.eclipse.swt.graphics.GC;\r
-import org.eclipse.swt.graphics.Point;\r
-import org.eclipse.swt.graphics.Rectangle;\r
-import org.eclipse.swt.widgets.Composite;\r
-import org.eclipse.swt.widgets.Display;\r
-import org.eclipse.swt.widgets.Event;\r
-import org.eclipse.swt.widgets.Listener;\r
-import org.eclipse.swt.widgets.Menu;\r
-import org.eclipse.ui.internal.TrimUtil;\r
-import org.eclipse.ui.internal.WorkbenchMessages;\r
-import org.simantics.db.MonitorContext;\r
-import org.simantics.db.MonitorHandler;\r
-import org.simantics.db.Session;\r
-import org.simantics.db.SessionReference;\r
-import org.simantics.db.SessionVariables;\r
-import org.simantics.db.service.LifecycleSupport;\r
-import org.simantics.db.service.SessionMonitorSupport;\r
-\r
-/**\r
- * The graph request status control, which shows the current graph request state\r
- * of a workbench window in the window trim.\r
- * <p>\r
- * Adapted from Eclipse's Heap Status control.\r
- * </p>\r
- */\r
-public class GraphRequestStatusTrim extends Composite {\r
-\r
-    final String requestStatusMessage = "{0}R / {1}W";\r
-    final String requestToolTip = "Session: {0}\nPending: {1} read requests, {2} write requests";\r
-\r
-    private boolean armed;\r
-    //private final Image gcImage;\r
-    private final Color bgCol, lowMemCol, freeMemCol;\r
-    private Color topLeftCol;\r
-    private final Color bottomRightCol, sepCol, textCol;\r
-    //private Color armCol;\r
-    //private final Canvas button;\r
-    private final IPreferenceStore prefStore;\r
-    private final int updateInterval = 200;\r
-    private boolean hasChanged;\r
-    // start with 12x12\r
-    private Rectangle imgBounds = new Rectangle(0,0,12,12);\r
-\r
-    private SessionMonitorSupport session;\r
-    private MonitorContext monitorContext;\r
-    private long lastRedrawTime = 0;\r
-\r
-    class Status {\r
-        SessionReference sessionRef;\r
-        int reads;\r
-        int writes;\r
-\r
-        void clear() {\r
-            sessionRef = null;\r
-            reads = 0;\r
-            writes = 0;\r
-        }\r
-    }\r
-\r
-    private final Status status = new Status();\r
-\r
-    private final MonitorHandler monitorHandler = new MonitorHandler() {\r
-        @Override\r
-        public void valuesChanged(MonitorContext c) {\r
-            //updateStats();\r
-            long time = System.currentTimeMillis();\r
-            // Require that 100ms has passed before refreshing again.\r
-            if ((time - 100) > lastRedrawTime) {\r
-                lastRedrawTime = time;\r
-                if (!isDisposed()) {\r
-                    getDisplay().asyncExec(timer);\r
-                }\r
-            }\r
-        }\r
-    };\r
-\r
-    private final Runnable timer = new Runnable() {\r
-        public void run() {\r
-            if (!isDisposed()) {\r
-                updateStats();\r
-                if (hasChanged) {\r
-                    updateToolTip();\r
-                    redraw();\r
-                    hasChanged = false;\r
-                }\r
-                getDisplay().timerExec(updateInterval, this);\r
-            }\r
-        }\r
-    };\r
-\r
-    private final IPropertyChangeListener prefListener = new IPropertyChangeListener() {\r
-        public void propertyChange(PropertyChangeEvent event) {\r
-//          if (IHeapStatusConstants.PREF_UPDATE_INTERVAL.equals(event.getProperty())) {\r
-//          setUpdateIntervalInMS(prefStore.getInt(IHeapStatusConstants.PREF_UPDATE_INTERVAL));\r
-//          }\r
-//          else if (IHeapStatusConstants.PREF_SHOW_MAX.equals(event.getProperty())) {\r
-//          showMax = prefStore.getBoolean(IHeapStatusConstants.PREF_SHOW_MAX);\r
-//          }\r
-        }\r
-    };\r
-\r
-    public void attachToSession(Session session) {\r
-        if (session != this.session) {\r
-            if (monitorContext != null) {\r
-                this.session.unregisterMonitor(monitorContext);\r
-                monitorContext = null;\r
-                this.session = null;\r
-                status.clear();\r
-            }\r
-\r
-            SessionMonitorSupport support = null;\r
-            if (session != null)\r
-                support = session.peekService(SessionMonitorSupport.class);\r
-            if (support == null) {\r
-                hasChanged = true;\r
-                return;\r
-            }\r
-\r
-            this.session = support;\r
-            monitorContext = this.session.registerMonitor(monitorHandler);\r
-            LifecycleSupport lifecycleSupport = session.getService(LifecycleSupport.class);\r
-            status.sessionRef = lifecycleSupport.getSessionReference();\r
-            getDisplay().asyncExec(timer);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Creates a new heap status control with the given parent, and using\r
-     * the given preference store to obtain settings such as the refresh\r
-     * interval.\r
-     * \r
-     * @param parent the parent composite\r
-     * @param prefStore the preference store\r
-     */\r
-    public GraphRequestStatusTrim(Composite parent, IPreferenceStore prefStore) {\r
-        super(parent, SWT.NONE);\r
-\r
-        this.prefStore = prefStore;\r
-        prefStore.addPropertyChangeListener(prefListener);\r
-\r
-//        setUpdateIntervalInMS(prefStore.getInt(IHeapStatusConstants.PREF_UPDATE_INTERVAL));\r
-//        showMax = prefStore.getBoolean(IHeapStatusConstants.PREF_SHOW_MAX);\r
-\r
-        //button = new Canvas(this, SWT.NONE);\r
-\r
-//        ImageDescriptor imageDesc = SimanticsUI.getImageDescriptor("icons/etool16/wrench.png"); //$NON-NLS-1$\r
-//        gcImage = imageDesc.createImage();\r
-//        if (gcImage != null) {\r
-//            imgBounds = gcImage.getBounds();\r
-//        }\r
-        Display display = getDisplay();\r
-//        usedMemCol = display.getSystemColor(SWT.COLOR_INFO_BACKGROUND);\r
-        lowMemCol = new Color(display, 255, 70, 70);  // medium red\r
-        freeMemCol = new Color(display, 255, 190, 125);  // light orange\r
-        bgCol = display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);\r
-        sepCol = topLeftCol = /*armCol =*/ display.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);\r
-        bottomRightCol = display.getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW);\r
-        textCol = display.getSystemColor(SWT.COLOR_INFO_FOREGROUND);\r
-//        markCol = textCol;\r
-\r
-        createContextMenu();\r
-\r
-        Listener listener = new Listener() {\r
-\r
-            public void handleEvent(Event event) {\r
-                switch (event.type) {\r
-                    case SWT.Dispose:\r
-                        doDispose();\r
-                        break;\r
-//                    case SWT.Resize:\r
-//                        Rectangle rect = getClientArea();\r
-//                        button.setBounds(rect.width - imgBounds.width - 1, 1, imgBounds.width, rect.height - 2);\r
-//                        break;\r
-                    case SWT.Paint:\r
-                        if (event.widget == GraphRequestStatusTrim.this) {\r
-                            paintComposite(event.gc);\r
-                        }\r
-//                        else if (event.widget == button) {\r
-//                            paintButton(event.gc);\r
-//                        }\r
-                        break;\r
-                    case SWT.MouseUp:\r
-                        if (event.button == 1) {\r
-                            // TODO: if the DB is locked, somehow release it ?\r
-                            arm(false);\r
-                        }\r
-                        break;\r
-                    case SWT.MouseDown:\r
-                        if (event.button == 1) {\r
-                            if (event.widget == GraphRequestStatusTrim.this) {\r
-//                          setMark();\r
-//                            } else if (event.widget == button) {\r
-//                                arm(true);\r
-                            }\r
-                        }\r
-                        break;\r
-                    case SWT.MouseExit:\r
-                        arm(false);\r
-                        break;\r
-                }\r
-            }\r
-\r
-        };\r
-        addListener(SWT.Dispose, listener);\r
-        addListener(SWT.MouseDown, listener);\r
-        addListener(SWT.Paint, listener);\r
-        addListener(SWT.Resize, listener);\r
-//        button.addListener(SWT.MouseDown, listener);\r
-//        button.addListener(SWT.MouseExit, listener);\r
-//        button.addListener(SWT.MouseUp, listener);\r
-//        button.addListener(SWT.Paint, listener);\r
-\r
-        // make sure stats are updated before first paint\r
-        //updateStats();\r
-\r
-        getDisplay().asyncExec(new Runnable() {\r
-            public void run() {\r
-                if (!isDisposed()) {\r
-                    getDisplay().timerExec(updateInterval, timer);\r
-                }\r
-            }\r
-        });\r
-    }\r
-\r
-//    private void setUpdateIntervalInMS(int interval) {\r
-//        updateInterval = Math.max(100, interval);\r
-//    }\r
-\r
-    private void doDispose() {\r
-        prefStore.removePropertyChangeListener(prefListener);\r
-//        if (gcImage != null) {\r
-//            gcImage.dispose();\r
-//        }\r
-\r
-        if (lowMemCol != null) {\r
-            lowMemCol.dispose();\r
-        }\r
-        if (freeMemCol != null) {\r
-            freeMemCol.dispose();\r
-        }\r
-    }\r
-\r
-    /* (non-Javadoc)\r
-     * @see org.eclipse.swt.widgets.Composite#computeSize(int, int, boolean)\r
-     */\r
-    @Override\r
-    public Point computeSize(int wHint, int hHint, boolean changed) {\r
-        GC gc = new GC(this);\r
-        Point p = gc.textExtent("MMMMMMM");\r
-        int height = imgBounds.height;\r
-        // choose the largest of\r
-        //     - Text height + margins\r
-        //     - Image height + margins\r
-        //     - Default Trim heightin\r
-        height = Math.max(height, p.y) + 4;\r
-        height = Math.max(TrimUtil.TRIM_DEFAULT_HEIGHT, height);\r
-        gc.dispose();\r
-        return new Point(p.x + 2, height);\r
-    }\r
-\r
-    private void arm(boolean armed) {\r
-        if (this.armed == armed) {\r
-            return;\r
-        }\r
-        this.armed = armed;\r
-//        button.redraw();\r
-//        button.update();\r
-    }\r
-\r
-    /**\r
-     * Creates the context menu\r
-     */\r
-    private void createContextMenu() {\r
-        MenuManager menuMgr = new MenuManager();\r
-        menuMgr.setRemoveAllWhenShown(true);\r
-        menuMgr.addMenuListener(new IMenuListener() {\r
-            public void menuAboutToShow(IMenuManager menuMgr) {\r
-                fillMenu(menuMgr);\r
-            }\r
-        });\r
-        Menu menu = menuMgr.createContextMenu(this);\r
-        setMenu(menu);\r
-    }\r
-\r
-    private void fillMenu(IMenuManager menuMgr) {\r
-        //menuMgr.add(new ShowSessionsAction());\r
-        menuMgr.add(new CloseAction());\r
-    }\r
-\r
-//    private void paintButton(GC gc) {\r
-//        Rectangle rect = button.getClientArea();\r
-//\r
-//        if (armed) {\r
-//            gc.setBackground(armCol);\r
-//            gc.fillRectangle(rect.x, rect.y, rect.width, rect.height);\r
-//        }\r
-////        if (gcImage != null) {\r
-////            int by = (rect.height - imgBounds.height) / 2 + rect.y; // button y\r
-////            gc.drawImage(gcImage, rect.x, by);\r
-////        }\r
-//    }\r
-\r
-\r
-    private void paintComposite(GC gc) {\r
-        Rectangle rect = getClientArea();\r
-        int x = rect.x;\r
-        int y = rect.y;\r
-        int w = rect.width;\r
-        int h = rect.height;\r
-//        int bw = imgBounds.width; // button width\r
-        int bw = 0;\r
-        int dx = x + w - bw - 2; // divider x\r
-//        int sw = w - bw - 3; // status width\r
-//        int uw = (int) (sw * usedMem / totalMem); // used mem width\r
-//        int ux = x + 1 + uw; // used mem right edge\r
-\r
-        gc.setBackground(bgCol);\r
-        gc.fillRectangle(rect);\r
-        gc.setForeground(sepCol);\r
-        gc.drawLine(dx, y, dx, y + h);\r
-//        gc.drawLine(ux, y, ux, y + h);\r
-        gc.setForeground(topLeftCol);\r
-        gc.drawLine(x, y, x+w, y);\r
-        gc.drawLine(x, y, x, y+h);\r
-        gc.setForeground(bottomRightCol);\r
-        gc.drawLine(x+w-1, y, x+w-1, y+h);\r
-        gc.drawLine(x, y+h-1, x+w, y+h-1);\r
-\r
-//        gc.setBackground(usedMemCol);\r
-//        gc.fillRectangle(x + 1, y + 1, uw, h - 2);\r
-\r
-        String reads = String.valueOf(status.reads);\r
-        String writes = String.valueOf(status.writes);\r
-        String s = NLS.bind(requestStatusMessage, new String[] { reads, writes });\r
-\r
-        Point p = gc.textExtent(s);\r
-        //int sx = (rect.width - 15 - p.x) / 2 + rect.x + 1;\r
-        int sx = (rect.width - 2 - p.x) / 2 + rect.x + 1;\r
-        int sy = (rect.height - 2 - p.y) / 2 + rect.y + 1;\r
-        gc.setForeground(textCol);\r
-        gc.setAlpha(192);\r
-        gc.drawString(s, sx, sy, true);\r
-\r
-        // draw an I-shaped bar in the foreground colour for the mark (if present)\r
-//        if (mark != -1) {\r
-//            int ssx = (int) (sw * mark / totalMem) + x + 1;\r
-//            paintMark(gc, ssx, y, h);\r
-//        }\r
-    }\r
-\r
-//     private void paintMark(GC gc, int x, int y, int h) {\r
-//        gc.setForeground(markCol);\r
-//        gc.drawLine(x, y+1, x, y+h-2);\r
-//        gc.drawLine(x-1, y+1, x+1, y+1);\r
-//        gc.drawLine(x-1, y+h-2, x+1, y+h-2);\r
-//     }\r
-\r
-    private void updateStats() {\r
-        if (monitorContext == null)\r
-            return;\r
-\r
-        int reads = monitorContext.getInteger(SessionVariables.QUEUED_READS);\r
-        int writes = monitorContext.getInteger(SessionVariables.QUEUED_WRITES);\r
-        if (reads != status.reads) {\r
-            status.reads = reads;\r
-            this.hasChanged = true;\r
-        }\r
-        if (writes != status.writes) {\r
-            status.writes = writes;\r
-            this.hasChanged = true;\r
-        }\r
-    }\r
-\r
-    private void updateToolTip() {\r
-        String server = "";\r
-        if (status.sessionRef != null)\r
-            server = status.sessionRef.getServerReference().toString();\r
-        String reads = String.valueOf(status.reads);\r
-        String writes = String.valueOf(status.writes);\r
-        String toolTip = NLS.bind(requestToolTip, new String[] { server, reads, writes });\r
-        if (!toolTip.equals(getToolTipText())) {\r
-            setToolTipText(toolTip);\r
-        }\r
-    }\r
-\r
-\r
-    class ShowSessionsAction extends Action{\r
-        ShowSessionsAction(){\r
-            super("Show Local Sessions");\r
-        }\r
-\r
-        /* (non-Javadoc)\r
-         * @see org.eclipse.jface.action.IAction#run()\r
-         */\r
-        @Override\r
-        public void run(){\r
-        }\r
-    }\r
-\r
-    class CloseAction extends Action{\r
-        CloseAction(){\r
-            super(WorkbenchMessages.WorkbenchWindow_close);\r
-        }\r
-\r
-        /* (non-Javadoc)\r
-         * @see org.eclipse.jface.action.IAction#run()\r
-         */\r
-        @Override\r
-        public void run(){\r
-            dispose();\r
-        }\r
-    }\r
-\r
-}\r
-\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.workbench.internal.contributions;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.ui.internal.TrimUtil;
+import org.eclipse.ui.internal.WorkbenchMessages;
+import org.simantics.db.MonitorContext;
+import org.simantics.db.MonitorHandler;
+import org.simantics.db.Session;
+import org.simantics.db.SessionReference;
+import org.simantics.db.SessionVariables;
+import org.simantics.db.service.LifecycleSupport;
+import org.simantics.db.service.SessionMonitorSupport;
+
+/**
+ * The graph request status control, which shows the current graph request state
+ * of a workbench window in the window trim.
+ * <p>
+ * Adapted from Eclipse's Heap Status control.
+ * </p>
+ */
+public class GraphRequestStatusTrim extends Composite {
+
+    final String requestStatusMessage = "{0}R / {1}W";
+    final String requestToolTip = "Session: {0}\nPending: {1} read requests, {2} write requests";
+
+    private boolean armed;
+    //private final Image gcImage;
+    private final Color bgCol, lowMemCol, freeMemCol;
+    private Color topLeftCol;
+    private final Color bottomRightCol, sepCol, textCol;
+    //private Color armCol;
+    //private final Canvas button;
+    private final IPreferenceStore prefStore;
+    private final int updateInterval = 200;
+    private boolean hasChanged;
+    // start with 12x12
+    private Rectangle imgBounds = new Rectangle(0,0,12,12);
+
+    private SessionMonitorSupport session;
+    private MonitorContext monitorContext;
+    private long lastRedrawTime = 0;
+
+    class Status {
+        SessionReference sessionRef;
+        int reads;
+        int writes;
+
+        void clear() {
+            sessionRef = null;
+            reads = 0;
+            writes = 0;
+        }
+    }
+
+    private final Status status = new Status();
+
+    private final MonitorHandler monitorHandler = new MonitorHandler() {
+        @Override
+        public void valuesChanged(MonitorContext c) {
+            //updateStats();
+            long time = System.currentTimeMillis();
+            // Require that 100ms has passed before refreshing again.
+            if ((time - 100) > lastRedrawTime) {
+                lastRedrawTime = time;
+                if (!isDisposed()) {
+                    getDisplay().asyncExec(timer);
+                }
+            }
+        }
+    };
+
+    private final Runnable timer = new Runnable() {
+        public void run() {
+            if (!isDisposed()) {
+                updateStats();
+                if (hasChanged) {
+                    updateToolTip();
+                    redraw();
+                    hasChanged = false;
+                }
+                getDisplay().timerExec(updateInterval, this);
+            }
+        }
+    };
+
+    private final IPropertyChangeListener prefListener = new IPropertyChangeListener() {
+        public void propertyChange(PropertyChangeEvent event) {
+//          if (IHeapStatusConstants.PREF_UPDATE_INTERVAL.equals(event.getProperty())) {
+//          setUpdateIntervalInMS(prefStore.getInt(IHeapStatusConstants.PREF_UPDATE_INTERVAL));
+//          }
+//          else if (IHeapStatusConstants.PREF_SHOW_MAX.equals(event.getProperty())) {
+//          showMax = prefStore.getBoolean(IHeapStatusConstants.PREF_SHOW_MAX);
+//          }
+        }
+    };
+
+    public void attachToSession(Session session) {
+        if (session != this.session) {
+            if (monitorContext != null) {
+                this.session.unregisterMonitor(monitorContext);
+                monitorContext = null;
+                this.session = null;
+                status.clear();
+            }
+
+            SessionMonitorSupport support = null;
+            if (session != null)
+                support = session.peekService(SessionMonitorSupport.class);
+            if (support == null) {
+                hasChanged = true;
+                return;
+            }
+
+            this.session = support;
+            monitorContext = this.session.registerMonitor(monitorHandler);
+            LifecycleSupport lifecycleSupport = session.getService(LifecycleSupport.class);
+            status.sessionRef = lifecycleSupport.getSessionReference();
+            getDisplay().asyncExec(timer);
+        }
+    }
+
+    /**
+     * Creates a new heap status control with the given parent, and using
+     * the given preference store to obtain settings such as the refresh
+     * interval.
+     * 
+     * @param parent the parent composite
+     * @param prefStore the preference store
+     */
+    public GraphRequestStatusTrim(Composite parent, IPreferenceStore prefStore) {
+        super(parent, SWT.NONE);
+
+        this.prefStore = prefStore;
+        prefStore.addPropertyChangeListener(prefListener);
+
+//        setUpdateIntervalInMS(prefStore.getInt(IHeapStatusConstants.PREF_UPDATE_INTERVAL));
+//        showMax = prefStore.getBoolean(IHeapStatusConstants.PREF_SHOW_MAX);
+
+        //button = new Canvas(this, SWT.NONE);
+
+//        ImageDescriptor imageDesc = SimanticsUI.getImageDescriptor("icons/etool16/wrench.png"); //$NON-NLS-1$
+//        gcImage = imageDesc.createImage();
+//        if (gcImage != null) {
+//            imgBounds = gcImage.getBounds();
+//        }
+        Display display = getDisplay();
+//        usedMemCol = display.getSystemColor(SWT.COLOR_INFO_BACKGROUND);
+        lowMemCol = new Color(display, 255, 70, 70);  // medium red
+        freeMemCol = new Color(display, 255, 190, 125);  // light orange
+        bgCol = display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
+        sepCol = topLeftCol = /*armCol =*/ display.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
+        bottomRightCol = display.getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW);
+        textCol = display.getSystemColor(SWT.COLOR_INFO_FOREGROUND);
+//        markCol = textCol;
+
+        createContextMenu();
+
+        Listener listener = new Listener() {
+
+            public void handleEvent(Event event) {
+                switch (event.type) {
+                    case SWT.Dispose:
+                        doDispose();
+                        break;
+//                    case SWT.Resize:
+//                        Rectangle rect = getClientArea();
+//                        button.setBounds(rect.width - imgBounds.width - 1, 1, imgBounds.width, rect.height - 2);
+//                        break;
+                    case SWT.Paint:
+                        if (event.widget == GraphRequestStatusTrim.this) {
+                            paintComposite(event.gc);
+                        }
+//                        else if (event.widget == button) {
+//                            paintButton(event.gc);
+//                        }
+                        break;
+                    case SWT.MouseUp:
+                        if (event.button == 1) {
+                            // TODO: if the DB is locked, somehow release it ?
+                            arm(false);
+                        }
+                        break;
+                    case SWT.MouseDown:
+                        if (event.button == 1) {
+                            if (event.widget == GraphRequestStatusTrim.this) {
+//                          setMark();
+//                            } else if (event.widget == button) {
+//                                arm(true);
+                            }
+                        }
+                        break;
+                    case SWT.MouseExit:
+                        arm(false);
+                        break;
+                }
+            }
+
+        };
+        addListener(SWT.Dispose, listener);
+        addListener(SWT.MouseDown, listener);
+        addListener(SWT.Paint, listener);
+        addListener(SWT.Resize, listener);
+//        button.addListener(SWT.MouseDown, listener);
+//        button.addListener(SWT.MouseExit, listener);
+//        button.addListener(SWT.MouseUp, listener);
+//        button.addListener(SWT.Paint, listener);
+
+        // make sure stats are updated before first paint
+        //updateStats();
+
+        getDisplay().asyncExec(new Runnable() {
+            public void run() {
+                if (!isDisposed()) {
+                    getDisplay().timerExec(updateInterval, timer);
+                }
+            }
+        });
+    }
+
+//    private void setUpdateIntervalInMS(int interval) {
+//        updateInterval = Math.max(100, interval);
+//    }
+
+    private void doDispose() {
+        prefStore.removePropertyChangeListener(prefListener);
+//        if (gcImage != null) {
+//            gcImage.dispose();
+//        }
+
+        if (lowMemCol != null) {
+            lowMemCol.dispose();
+        }
+        if (freeMemCol != null) {
+            freeMemCol.dispose();
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.swt.widgets.Composite#computeSize(int, int, boolean)
+     */
+    @Override
+    public Point computeSize(int wHint, int hHint, boolean changed) {
+        GC gc = new GC(this);
+        Point p = gc.textExtent("MMMMMMM");
+        int height = imgBounds.height;
+        // choose the largest of
+        //     - Text height + margins
+        //     - Image height + margins
+        //     - Default Trim heightin
+        height = Math.max(height, p.y) + 4;
+        height = Math.max(TrimUtil.TRIM_DEFAULT_HEIGHT, height);
+        gc.dispose();
+        return new Point(p.x + 2, height);
+    }
+
+    private void arm(boolean armed) {
+        if (this.armed == armed) {
+            return;
+        }
+        this.armed = armed;
+//        button.redraw();
+//        button.update();
+    }
+
+    /**
+     * Creates the context menu
+     */
+    private void createContextMenu() {
+        MenuManager menuMgr = new MenuManager();
+        menuMgr.setRemoveAllWhenShown(true);
+        menuMgr.addMenuListener(new IMenuListener() {
+            public void menuAboutToShow(IMenuManager menuMgr) {
+                fillMenu(menuMgr);
+            }
+        });
+        Menu menu = menuMgr.createContextMenu(this);
+        setMenu(menu);
+    }
+
+    private void fillMenu(IMenuManager menuMgr) {
+        //menuMgr.add(new ShowSessionsAction());
+        menuMgr.add(new CloseAction());
+    }
+
+//    private void paintButton(GC gc) {
+//        Rectangle rect = button.getClientArea();
+//
+//        if (armed) {
+//            gc.setBackground(armCol);
+//            gc.fillRectangle(rect.x, rect.y, rect.width, rect.height);
+//        }
+////        if (gcImage != null) {
+////            int by = (rect.height - imgBounds.height) / 2 + rect.y; // button y
+////            gc.drawImage(gcImage, rect.x, by);
+////        }
+//    }
+
+
+    private void paintComposite(GC gc) {
+        Rectangle rect = getClientArea();
+        int x = rect.x;
+        int y = rect.y;
+        int w = rect.width;
+        int h = rect.height;
+//        int bw = imgBounds.width; // button width
+        int bw = 0;
+        int dx = x + w - bw - 2; // divider x
+//        int sw = w - bw - 3; // status width
+//        int uw = (int) (sw * usedMem / totalMem); // used mem width
+//        int ux = x + 1 + uw; // used mem right edge
+
+        gc.setBackground(bgCol);
+        gc.fillRectangle(rect);
+        gc.setForeground(sepCol);
+        gc.drawLine(dx, y, dx, y + h);
+//        gc.drawLine(ux, y, ux, y + h);
+        gc.setForeground(topLeftCol);
+        gc.drawLine(x, y, x+w, y);
+        gc.drawLine(x, y, x, y+h);
+        gc.setForeground(bottomRightCol);
+        gc.drawLine(x+w-1, y, x+w-1, y+h);
+        gc.drawLine(x, y+h-1, x+w, y+h-1);
+
+//        gc.setBackground(usedMemCol);
+//        gc.fillRectangle(x + 1, y + 1, uw, h - 2);
+
+        String reads = String.valueOf(status.reads);
+        String writes = String.valueOf(status.writes);
+        String s = NLS.bind(requestStatusMessage, new String[] { reads, writes });
+
+        Point p = gc.textExtent(s);
+        //int sx = (rect.width - 15 - p.x) / 2 + rect.x + 1;
+        int sx = (rect.width - 2 - p.x) / 2 + rect.x + 1;
+        int sy = (rect.height - 2 - p.y) / 2 + rect.y + 1;
+        gc.setForeground(textCol);
+        gc.setAlpha(192);
+        gc.drawString(s, sx, sy, true);
+
+        // draw an I-shaped bar in the foreground colour for the mark (if present)
+//        if (mark != -1) {
+//            int ssx = (int) (sw * mark / totalMem) + x + 1;
+//            paintMark(gc, ssx, y, h);
+//        }
+    }
+
+//     private void paintMark(GC gc, int x, int y, int h) {
+//        gc.setForeground(markCol);
+//        gc.drawLine(x, y+1, x, y+h-2);
+//        gc.drawLine(x-1, y+1, x+1, y+1);
+//        gc.drawLine(x-1, y+h-2, x+1, y+h-2);
+//     }
+
+    private void updateStats() {
+        if (monitorContext == null)
+            return;
+
+        int reads = monitorContext.getInteger(SessionVariables.QUEUED_READS);
+        int writes = monitorContext.getInteger(SessionVariables.QUEUED_WRITES);
+        if (reads != status.reads) {
+            status.reads = reads;
+            this.hasChanged = true;
+        }
+        if (writes != status.writes) {
+            status.writes = writes;
+            this.hasChanged = true;
+        }
+    }
+
+    private void updateToolTip() {
+        String server = "";
+        if (status.sessionRef != null)
+            server = status.sessionRef.getServerReference().toString();
+        String reads = String.valueOf(status.reads);
+        String writes = String.valueOf(status.writes);
+        String toolTip = NLS.bind(requestToolTip, new String[] { server, reads, writes });
+        if (!toolTip.equals(getToolTipText())) {
+            setToolTipText(toolTip);
+        }
+    }
+
+
+    class ShowSessionsAction extends Action{
+        ShowSessionsAction(){
+            super("Show Local Sessions");
+        }
+
+        /* (non-Javadoc)
+         * @see org.eclipse.jface.action.IAction#run()
+         */
+        @Override
+        public void run(){
+        }
+    }
+
+    class CloseAction extends Action{
+        CloseAction(){
+            super(WorkbenchMessages.WorkbenchWindow_close);
+        }
+
+        /* (non-Javadoc)
+         * @see org.eclipse.jface.action.IAction#run()
+         */
+        @Override
+        public void run(){
+            dispose();
+        }
+    }
+
+}
+