diff --git a/com.minres.scviewer.e4.application/.classpath b/com.minres.scviewer.e4.application/.classpath new file mode 100644 index 0000000..098194c --- /dev/null +++ b/com.minres.scviewer.e4.application/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/com.minres.scviewer.e4.application/.gitignore b/com.minres.scviewer.e4.application/.gitignore new file mode 100644 index 0000000..ae3c172 --- /dev/null +++ b/com.minres.scviewer.e4.application/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/com.minres.scviewer.e4.application/.project b/com.minres.scviewer.e4.application/.project new file mode 100644 index 0000000..5c5d8a7 --- /dev/null +++ b/com.minres.scviewer.e4.application/.project @@ -0,0 +1,33 @@ + + + com.minres.scviewer.e4.application + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.ds.core.builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/com.minres.scviewer.e4.application/.settings/org.eclipse.jdt.core.prefs b/com.minres.scviewer.e4.application/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..f42de36 --- /dev/null +++ b/com.minres.scviewer.e4.application/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.7 diff --git a/com.minres.scviewer.e4.application/.settings/org.eclipse.pde.core.prefs b/com.minres.scviewer.e4.application/.settings/org.eclipse.pde.core.prefs new file mode 100644 index 0000000..f29e940 --- /dev/null +++ b/com.minres.scviewer.e4.application/.settings/org.eclipse.pde.core.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +pluginProject.extensions=false +resolve.requirebundle=false diff --git a/com.minres.scviewer.e4.application/Application.e4xmi b/com.minres.scviewer.e4.application/Application.e4xmi new file mode 100644 index 0000000..3dd80be --- /dev/null +++ b/com.minres.scviewer.e4.application/Application.e4xmi @@ -0,0 +1,190 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + glue + move_after:PerspectiveSpacer + SHOW_RESTORE_MENU + + + + + + + + + + + + + + + + + + + + + + categoryTag:General + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.minres.scviewer.e4.application/META-INF/MANIFEST.MF b/com.minres.scviewer.e4.application/META-INF/MANIFEST.MF new file mode 100644 index 0000000..5d29a8c --- /dev/null +++ b/com.minres.scviewer.e4.application/META-INF/MANIFEST.MF @@ -0,0 +1,29 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Application +Bundle-SymbolicName: com.minres.scviewer.e4.application;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: MINRES Technologies GmbH +Require-Bundle: javax.inject;bundle-version="1.0.0", + org.eclipse.core.runtime;bundle-version="3.11.1", + org.eclipse.swt;bundle-version="3.104.1", + org.eclipse.e4.ui.model.workbench;bundle-version="1.1.100", + org.eclipse.jface;bundle-version="3.11.0", + org.eclipse.e4.ui.services;bundle-version="1.2.0", + org.eclipse.e4.ui.workbench;bundle-version="1.3.0", + org.eclipse.e4.core.di;bundle-version="1.5.0", + org.eclipse.e4.ui.di;bundle-version="1.1.0", + org.eclipse.e4.core.contexts;bundle-version="1.4.0", + com.minres.scviewer.database.swt;bundle-version="1.0.0", + com.minres.scviewer.database;bundle-version="1.0.0", + org.eclipse.equinox.ds;bundle-version="1.4.300", + org.eclipse.equinox.util;bundle-version="1.0.500", + org.eclipse.osgi.services;bundle-version="3.5.0", + org.eclipse.e4.core.services;bundle-version="2.0.0", + org.eclipse.osgi.services;bundle-version="3.5.0", + org.eclipse.core.jobs, + org.eclipse.osgi, + org.eclipse.wb.core.lib +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Import-Package: com.minres.scviewer.database, + javax.inject;version="1.0.0" diff --git a/com.minres.scviewer.e4.application/build.properties b/com.minres.scviewer.e4.application/build.properties new file mode 100644 index 0000000..d21f19d --- /dev/null +++ b/com.minres.scviewer.e4.application/build.properties @@ -0,0 +1,9 @@ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml,\ + plugin.xml,\ + Application.e4xmi,\ + icons/,\ + css/default.css +source.. = src/ diff --git a/com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.product b/com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.product new file mode 100644 index 0000000..7537fca --- /dev/null +++ b/com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.product @@ -0,0 +1,130 @@ + + + + + + + + + + + -clearPersistedState + + -XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.minres.scviewer.e4.application/css/default.css b/com.minres.scviewer.e4.application/css/default.css new file mode 100644 index 0000000..857a2b4 --- /dev/null +++ b/com.minres.scviewer.e4.application/css/default.css @@ -0,0 +1,205 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + * Lars Vogel - Bug 420836 + *******************************************************************************/ + +/* New ColorDefinitions for the E4 default theme */ +ThemesExtension { color-definition: + '#org-eclipse-ui-workbench-INACTIVE_UNSELECTED_TABS_COLOR_START', + '#org-eclipse-ui-workbench-INACTIVE_UNSELECTED_TABS_COLOR_END', + '#org-eclipse-ui-workbench-INACTIVE_TAB_OUTER_KEYLINE_COLOR', + '#org-eclipse-ui-workbench-INACTIVE_TAB_INNER_KEYLINE_COLOR', + '#org-eclipse-ui-workbench-INACTIVE_TAB_OUTLINE_COLOR', + '#org-eclipse-ui-workbench-ACTIVE_UNSELECTED_TABS_COLOR_START', + '#org-eclipse-ui-workbench-ACTIVE_UNSELECTED_TABS_COLOR_END', + '#org-eclipse-ui-workbench-ACTIVE_TAB_OUTER_KEYLINE_COLOR', + '#org-eclipse-ui-workbench-ACTIVE_TAB_INNER_KEYLINE_COLOR', + '#org-eclipse-ui-workbench-ACTIVE_TAB_OUTLINE_COLOR'; +} + +ColorDefinition#org-eclipse-ui-workbench-INACTIVE_UNSELECTED_TABS_COLOR_START { + color: #FFFFFF; + category: '#org-eclipse-ui-presentation-default'; + label: url('platform:/plugin/org.eclipse.ui.themes?message=INACTIVE_UNSELECTED_TABS_COLOR_START') +} + +ColorDefinition#org-eclipse-ui-workbench-INACTIVE_UNSELECTED_TABS_COLOR_END { + color: #FFFFFF; + category: '#org-eclipse-ui-presentation-default'; + label: url('platform:/plugin/org.eclipse.ui.themes?message=INACTIVE_UNSELECTED_TABS_COLOR_END'); +} + +ColorDefinition#org-eclipse-ui-workbench-INACTIVE_TAB_OUTER_KEYLINE_COLOR { + color: #FFFFFF; + category: '#org-eclipse-ui-presentation-default'; + label: url('platform:/plugin/org.eclipse.ui.themes?message=INACTIVE_TAB_OUTER_KEYLINE_COLOR'); +} + +ColorDefinition#org-eclipse-ui-workbench-INACTIVE_TAB_INNER_KEYLINE_COLOR { + color: #FFFFFF; + category: '#org-eclipse-ui-presentation-default'; + label: url('platform:/plugin/org.eclipse.ui.themes?message=INACTIVE_TAB_INNER_KEYLINE_COLOR'); +} + +ColorDefinition#org-eclipse-ui-workbench-INACTIVE_TAB_OUTLINE_COLOR { + color: #B6BCCC; + category: '#org-eclipse-ui-presentation-default'; + label: url('platform:/plugin/org.eclipse.ui.themes?message=INACTIVE_TAB_OUTLINE_COLOR'); +} + +ColorDefinition#org-eclipse-ui-workbench-ACTIVE_UNSELECTED_TABS_COLOR_START { + color: #FFFFFF; + category: '#org-eclipse-ui-presentation-default'; + label: url('platform:/plugin/org.eclipse.ui.themes?message=ACTIVE_UNSELECTED_TABS_COLOR_START'); +} + +ColorDefinition#org-eclipse-ui-workbench-ACTIVE_UNSELECTED_TABS_COLOR_END { + color: #FFFFFF; + category: '#org-eclipse-ui-presentation-default'; + label: url('platform:/plugin/org.eclipse.ui.themes?message=ACTIVE_UNSELECTED_TABS_COLOR_END'); +} + +ColorDefinition#org-eclipse-ui-workbench-ACTIVE_TAB_OUTER_KEYLINE_COLOR { + color: #CCCCCC; + category: '#org-eclipse-ui-presentation-default'; + label: url('platform:/plugin/org.eclipse.ui.themes?message=ACTIVE_TAB_OUTER_KEYLINE_COLOR'); +} + +ColorDefinition#org-eclipse-ui-workbench-ACTIVE_TAB_INNER_KEYLINE_COLOR { + color: #FFFFFF; + category: '#org-eclipse-ui-presentation-default'; + label: url('platform:/plugin/org.eclipse.ui.themes?message=ACTIVE_TAB_INNER_KEYLINE_COLOR'); +} + +ColorDefinition#org-eclipse-ui-workbench-ACTIVE_TAB_OUTLINE_COLOR { + color: #B6BCCC; + category: '#org-eclipse-ui-presentation-default'; + label: url('platform:/plugin/org.eclipse.ui.themes?message=ACTIVE_TAB_OUTLINE_COLOR'); +} + +/* Already existing ColorDefinitions overridden for the E4 default theme */ +ColorDefinition#org-eclipse-ui-workbench-INACTIVE_TAB_BG_START { + color: #dddfe5; +} + +ColorDefinition#org-eclipse-ui-workbench-INACTIVE_TAB_BG_END { + color: #FFFFFF; +} + +ColorDefinition#org-eclipse-ui-workbench-ACTIVE_TAB_BG_START{ + color: #FFFFFF; +} + +ColorDefinition#org-eclipse-ui-workbench-ACTIVE_TAB_BG_END { + color: #FFFFFF; +} + +ColorDefinition#org-eclipse-ui-workbench-ACTIVE_NOFOCUS_TAB_BG_START { + color: #FFFFFF; +} + +ColorDefinition#org-eclipse-ui-workbench-ACTIVE_NOFOCUS_TAB_BG_END { + color: #FFFFFF; +} + +ColorDefinition#org-eclipse-ui-workbench-ACTIVE_NOFOCUS_TAB_TEXT_COLOR { + color: #000000; +} + +.MTrimmedWindow.topLevel { + margin-top: 3px; + margin-bottom: 3px; + margin-left: 3px; + margin-right: 3px; +} + +.MPart.busy { + font-style: italic; +} + +.MPart.highlighted { + font-weight: bold; +} + +.MPartStack, .MPart { + font-family: '#org-eclipse-ui-workbench-TAB_TEXT_FONT'; +} + +CTabItem:selected { + color: '#org-eclipse-ui-workbench-ACTIVE_TAB_TEXT_COLOR'; +} + +.MPartStack { + swt-tab-renderer: url('bundleclass://org.eclipse.e4.ui.workbench.renderers.swt/org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering'); + swt-selected-tab-fill: '#org-eclipse-ui-workbench-INACTIVE_TAB_BG_START' '#org-eclipse-ui-workbench-INACTIVE_TAB_BG_END' 100% 100%; + swt-unselected-tabs-color: '#org-eclipse-ui-workbench-INACTIVE_UNSELECTED_TABS_COLOR_START' '#org-eclipse-ui-workbench-INACTIVE_UNSELECTED_TABS_COLOR_END' 100% 100%; + swt-outer-keyline-color: '#org-eclipse-ui-workbench-INACTIVE_TAB_OUTER_KEYLINE_COLOR'; + swt-inner-keyline-color: '#org-eclipse-ui-workbench-INACTIVE_TAB_INNER_KEYLINE_COLOR'; + swt-tab-outline: '#org-eclipse-ui-workbench-INACTIVE_TAB_OUTLINE_COLOR'; + padding: 0px 2px 2px; + swt-shadow-visible: false; + swt-mru-visible: false; + color: '#org-eclipse-ui-workbench-INACTIVE_TAB_TEXT_COLOR'; +} + +.MPartStack.active { + swt-selected-tab-fill: '#org-eclipse-ui-workbench-ACTIVE_TAB_BG_START' '#org-eclipse-ui-workbench-ACTIVE_TAB_BG_END' 100% 100%; + swt-unselected-tabs-color: '#org-eclipse-ui-workbench-ACTIVE_UNSELECTED_TABS_COLOR_START' '#org-eclipse-ui-workbench-ACTIVE_UNSELECTED_TABS_COLOR_END' 100% 100%; + swt-outer-keyline-color: '#org-eclipse-ui-workbench-ACTIVE_TAB_OUTER_KEYLINE_COLOR'; + swt-inner-keyline-color: '#org-eclipse-ui-workbench-ACTIVE_TAB_INNER_KEYLINE_COLOR'; + swt-tab-outline: '#org-eclipse-ui-workbench-ACTIVE_TAB_OUTLINE_COLOR'; + swt-shadow-visible: false; +} + +.MPartStack.active.noFocus { + swt-selected-tab-fill: '#org-eclipse-ui-workbench-ACTIVE_NOFOCUS_TAB_BG_START' '#org-eclipse-ui-workbench-ACTIVE_NOFOCUS_TAB_BG_END' 100% 100%; +} + +.MPartStack.active.noFocus > CTabItem:selected { + color: '#org-eclipse-ui-workbench-ACTIVE_NOFOCUS_TAB_TEXT_COLOR'; +} + +#PerspectiveSwitcher { + eclipse-perspective-keyline-color: #AAB0BF #AAB0BF; +} + +.MToolControl.TrimStack { + frame-image: url(./winXPTSFrame.png); + handle-image: url(./winXPHandle.png); + frame-cuts: 5px 1px 5px 16px; +} + +.MToolBar.Draggable { + handle-image: url(./dragHandle.png); +} + +.MToolControl.Draggable { + handle-image: url(./dragHandle.png); +} + +.DragFeedback { + background-color: COLOR-WIDGET-NORMAL-SHADOW; +} + +.ModifiedDragFeedback { + background-color: #A0A000; +} + +.MPartStack > Composite { + background-color: '#org-eclipse-ui-workbench-INACTIVE_TAB_BG_END'; +} + +.MPartStack.active > Composite { + background-color: '#org-eclipse-ui-workbench-ACTIVE_TAB_BG_END'; +} + +.MPartStack.active.noFocus > Composite { + background-color: '#org-eclipse-ui-workbench-ACTIVE_NOFOCUS_TAB_BG_END'; +} diff --git a/com.minres.scviewer.e4.application/icons/SCViewer.icns b/com.minres.scviewer.e4.application/icons/SCViewer.icns new file mode 100644 index 0000000..c4727f8 Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/SCViewer.icns differ diff --git a/com.minres.scviewer.e4.application/icons/SCViewer.ico b/com.minres.scviewer.e4.application/icons/SCViewer.ico new file mode 100644 index 0000000..afd0d4f Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/SCViewer.ico differ diff --git a/com.minres.scviewer.e4.application/icons/SCViewer_128x32.png b/com.minres.scviewer.e4.application/icons/SCViewer_128x32.png new file mode 100644 index 0000000..f7fb7fc Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/SCViewer_128x32.png differ diff --git a/com.minres.scviewer.e4.application/icons/SCViewer_16x32.png b/com.minres.scviewer.e4.application/icons/SCViewer_16x32.png new file mode 100644 index 0000000..0b790d9 Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/SCViewer_16x32.png differ diff --git a/com.minres.scviewer.e4.application/icons/SCViewer_256x32.png b/com.minres.scviewer.e4.application/icons/SCViewer_256x32.png new file mode 100644 index 0000000..9cceaa6 Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/SCViewer_256x32.png differ diff --git a/com.minres.scviewer.e4.application/icons/SCViewer_32x32.png b/com.minres.scviewer.e4.application/icons/SCViewer_32x32.png new file mode 100644 index 0000000..2ffbcb6 Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/SCViewer_32x32.png differ diff --git a/com.minres.scviewer.e4.application/icons/SCViewer_48x32.png b/com.minres.scviewer.e4.application/icons/SCViewer_48x32.png new file mode 100644 index 0000000..3526a1e Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/SCViewer_48x32.png differ diff --git a/com.minres.scviewer.e4.application/icons/SCViewer_512.png b/com.minres.scviewer.e4.application/icons/SCViewer_512.png new file mode 100644 index 0000000..ba03ec8 Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/SCViewer_512.png differ diff --git a/com.minres.scviewer.e4.application/icons/SCViewer_64x32.png b/com.minres.scviewer.e4.application/icons/SCViewer_64x32.png new file mode 100644 index 0000000..304cd77 Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/SCViewer_64x32.png differ diff --git a/com.minres.scviewer.e4.application/icons/bullet_plus.png b/com.minres.scviewer.e4.application/icons/bullet_plus.png new file mode 100644 index 0000000..cd52e3c Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/bullet_plus.png differ diff --git a/com.minres.scviewer.e4.application/icons/cross.png b/com.minres.scviewer.e4.application/icons/cross.png new file mode 100644 index 0000000..1514d51 Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/cross.png differ diff --git a/com.minres.scviewer.e4.application/icons/database.png b/com.minres.scviewer.e4.application/icons/database.png new file mode 100755 index 0000000..3d09261 Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/database.png differ diff --git a/com.minres.scviewer.e4.application/icons/down_blue.png b/com.minres.scviewer.e4.application/icons/down_blue.png new file mode 100644 index 0000000..73d09f1 Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/down_blue.png differ diff --git a/com.minres.scviewer.e4.application/icons/folder.png b/com.minres.scviewer.e4.application/icons/folder.png new file mode 100755 index 0000000..784e8fa Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/folder.png differ diff --git a/com.minres.scviewer.e4.application/icons/folder_database.png b/com.minres.scviewer.e4.application/icons/folder_database.png new file mode 100644 index 0000000..5193e2e Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/folder_database.png differ diff --git a/com.minres.scviewer.e4.application/icons/play_blue.png b/com.minres.scviewer.e4.application/icons/play_blue.png new file mode 100644 index 0000000..cb75b58 Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/play_blue.png differ diff --git a/com.minres.scviewer.e4.application/icons/play_green.png b/com.minres.scviewer.e4.application/icons/play_green.png new file mode 100644 index 0000000..3a1d7b2 Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/play_green.png differ diff --git a/com.minres.scviewer.e4.application/icons/reverse_blue.png b/com.minres.scviewer.e4.application/icons/reverse_blue.png new file mode 100644 index 0000000..d7bdcd6 Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/reverse_blue.png differ diff --git a/com.minres.scviewer.e4.application/icons/reverse_green.png b/com.minres.scviewer.e4.application/icons/reverse_green.png new file mode 100644 index 0000000..57e7bd2 Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/reverse_green.png differ diff --git a/com.minres.scviewer.e4.application/icons/save_edit.png b/com.minres.scviewer.e4.application/icons/save_edit.png new file mode 100644 index 0000000..2c598e5 Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/save_edit.png differ diff --git a/com.minres.scviewer.e4.application/icons/scviewer.gif b/com.minres.scviewer.e4.application/icons/scviewer.gif new file mode 100644 index 0000000..229a663 Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/scviewer.gif differ diff --git a/com.minres.scviewer.e4.application/icons/scviewer.png b/com.minres.scviewer.e4.application/icons/scviewer.png new file mode 100644 index 0000000..4e4a7b2 Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/scviewer.png differ diff --git a/com.minres.scviewer.e4.application/icons/signal.png b/com.minres.scviewer.e4.application/icons/signal.png new file mode 100644 index 0000000..9c96af9 Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/signal.png differ diff --git a/com.minres.scviewer.e4.application/icons/stream.png b/com.minres.scviewer.e4.application/icons/stream.png new file mode 100755 index 0000000..c32d25c Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/stream.png differ diff --git a/com.minres.scviewer.e4.application/icons/trash.png b/com.minres.scviewer.e4.application/icons/trash.png new file mode 100644 index 0000000..a84ea6b Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/trash.png differ diff --git a/com.minres.scviewer.e4.application/icons/up_blue.png b/com.minres.scviewer.e4.application/icons/up_blue.png new file mode 100644 index 0000000..642d2f9 Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/up_blue.png differ diff --git a/com.minres.scviewer.e4.application/icons/zoom.png b/com.minres.scviewer.e4.application/icons/zoom.png new file mode 100644 index 0000000..908612e Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/zoom.png differ diff --git a/com.minres.scviewer.e4.application/icons/zoom_in.png b/com.minres.scviewer.e4.application/icons/zoom_in.png new file mode 100644 index 0000000..cdf0a52 Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/zoom_in.png differ diff --git a/com.minres.scviewer.e4.application/icons/zoom_out.png b/com.minres.scviewer.e4.application/icons/zoom_out.png new file mode 100644 index 0000000..07bf98a Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/zoom_out.png differ diff --git a/com.minres.scviewer.e4.application/plugin.xml b/com.minres.scviewer.e4.application/plugin.xml new file mode 100644 index 0000000..f636fc6 --- /dev/null +++ b/com.minres.scviewer.e4.application/plugin.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/E4LifeCycle.java b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/E4LifeCycle.java new file mode 100644 index 0000000..36b07fa --- /dev/null +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/E4LifeCycle.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2014 TwelveTone LLC and others. + * 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: + * Steven Spungin - initial API and implementation + *******************************************************************************/ +package com.minres.scviewer.e4.application; + +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.ui.workbench.lifecycle.PostContextCreate; +import org.eclipse.e4.ui.workbench.lifecycle.PreSave; +import org.eclipse.e4.ui.workbench.lifecycle.ProcessAdditions; +import org.eclipse.e4.ui.workbench.lifecycle.ProcessRemovals; + +/** + * This is a stub implementation containing e4 LifeCycle annotated methods.
+ * There is a corresponding entry in plugin.xml (under the + * org.eclipse.core.runtime.products' extension point) that references + * this class. + **/ +@SuppressWarnings("restriction") +public class E4LifeCycle { + + @PostContextCreate + void postContextCreate(IEclipseContext workbenchContext) { + } + + @PreSave + void preSave(IEclipseContext workbenchContext) { + } + + @ProcessAdditions + void processAdditions(IEclipseContext workbenchContext) { + } + + @ProcessRemovals + void processRemovals(IEclipseContext workbenchContext) { + } +} diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/AboutHandler.java b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/AboutHandler.java new file mode 100644 index 0000000..4404732 --- /dev/null +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/AboutHandler.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2010 - 2013 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + * Lars Vogel - Bug 419770 + *******************************************************************************/ +package com.minres.scviewer.e4.application.handlers; + +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.widgets.Shell; + +public class AboutHandler { + @Execute + public void execute(Shell shell) { + MessageDialog.openInformation(shell, "About", "Eclipse 4 Application example."); + } +} diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/DeleteWaveformHandler.java b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/DeleteWaveformHandler.java new file mode 100644 index 0000000..ec88eed --- /dev/null +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/DeleteWaveformHandler.java @@ -0,0 +1,29 @@ + +package com.minres.scviewer.e4.application.handlers; + +import org.eclipse.e4.core.di.annotations.CanExecute; +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.workbench.modeling.ESelectionService; + +import com.minres.scviewer.database.IWaveform; +import com.minres.scviewer.e4.application.parts.WaveformViewerPart; + +public class DeleteWaveformHandler { + + @CanExecute + public Boolean canExecute(ESelectionService selectionService){ + Object o = selectionService.getSelection(); + return o instanceof IWaveform; + } + + @Execute + public void execute(ESelectionService selectionService, MPart activePart) { + Object o = activePart.getObject(); + Object sel = selectionService.getSelection(); + if(o instanceof WaveformViewerPart && sel instanceof IWaveform){ + ((WaveformViewerPart)o).removeStreamFromList((IWaveform) sel); + } + } + +} \ No newline at end of file diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/MoveWaveformHandler.java b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/MoveWaveformHandler.java new file mode 100644 index 0000000..67ba167 --- /dev/null +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/MoveWaveformHandler.java @@ -0,0 +1,38 @@ + +package com.minres.scviewer.e4.application.handlers; + +import javax.inject.Named; + +import org.eclipse.e4.core.di.annotations.CanExecute; +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.workbench.modeling.EPartService; +import org.eclipse.e4.ui.workbench.modeling.ESelectionService; + +import com.minres.scviewer.database.ITx; +import com.minres.scviewer.database.IWaveform; +import com.minres.scviewer.e4.application.parts.WaveformViewerPart; + +public class MoveWaveformHandler { + + static final String PARAMETER_ID="com.minres.scviewer.e4.application.command.movewaveformupCommand.parameter.dir"; + + @CanExecute + public Boolean canExecute(ESelectionService selectionService){ + Object o = selectionService.getSelection(); + return o instanceof IWaveform || o instanceof ITx; + } + + @Execute + public void execute(@Named(PARAMETER_ID) String param, EPartService partService) { + MPart part = partService.getActivePart(); + Object obj = part.getObject(); + if(obj instanceof WaveformViewerPart){ + if("up".equalsIgnoreCase(param)) + ((WaveformViewerPart)obj).moveSelected(-1); + else if("down".equalsIgnoreCase(param)) + ((WaveformViewerPart)obj).moveSelected(1); + } + } + +} \ No newline at end of file diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/NavigateEvent.java b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/NavigateEvent.java new file mode 100644 index 0000000..579dfe5 --- /dev/null +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/NavigateEvent.java @@ -0,0 +1,40 @@ + +package com.minres.scviewer.e4.application.handlers; + +import javax.inject.Named; + +import org.eclipse.e4.core.di.annotations.CanExecute; +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.workbench.modeling.EPartService; +import org.eclipse.e4.ui.workbench.modeling.ESelectionService; + +import com.minres.scviewer.database.ITx; +import com.minres.scviewer.database.IWaveform; +import com.minres.scviewer.database.swt.GotoDirection; +import com.minres.scviewer.e4.application.parts.WaveformViewerPart; + +public class NavigateEvent { + + final static String PARAMTER_ID="com.minres.scviewer.e4.application.command.navigateEventCommand.parameter.dir"; + + @CanExecute + public Boolean canExecute(ESelectionService selectionService){ + Object o = selectionService.getSelection(); + return o instanceof IWaveform || o instanceof ITx; + } + + @Execute + public void execute(@Named(PARAMTER_ID) String param, EPartService partService) { +// public void execute(EPartService partService) { +// String param="next"; + MPart part = partService.getActivePart(); + Object obj = part.getObject(); + if(obj instanceof WaveformViewerPart){ + if("next".equalsIgnoreCase(param)) + ((WaveformViewerPart)obj).moveCursor(GotoDirection.NEXT); + else if("prev".equalsIgnoreCase(param)) + ((WaveformViewerPart)obj).moveCursor(GotoDirection.PREV); + } + } +} \ No newline at end of file diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/NavigateTrans.java b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/NavigateTrans.java new file mode 100644 index 0000000..5d1bc0c --- /dev/null +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/NavigateTrans.java @@ -0,0 +1,37 @@ + +package com.minres.scviewer.e4.application.handlers; + +import javax.inject.Named; + +import org.eclipse.e4.core.di.annotations.CanExecute; +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.workbench.modeling.EPartService; +import org.eclipse.e4.ui.workbench.modeling.ESelectionService; + +import com.minres.scviewer.database.ITx; +import com.minres.scviewer.database.swt.GotoDirection; +import com.minres.scviewer.e4.application.parts.WaveformViewerPart; + +public class NavigateTrans { + + final static String PARAMTER_ID="com.minres.scviewer.e4.application.command.navigateTransCommand.parameter.dir"; + + @CanExecute + public Boolean canExecute(ESelectionService selectionService){ + Object o = selectionService.getSelection(); + return o instanceof ITx; + } + + @Execute + public void execute(@Named(PARAMTER_ID) String param, EPartService partService) { + MPart part = partService.getActivePart(); + Object obj = part.getObject(); + if(obj instanceof WaveformViewerPart){ + if("next".equalsIgnoreCase(param)) + ((WaveformViewerPart)obj).moveSelection(GotoDirection.NEXT); + else if("prev".equalsIgnoreCase(param)) + ((WaveformViewerPart)obj).moveSelection(GotoDirection.PREV); + } + } +} \ No newline at end of file diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/OpenHandler.java b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/OpenHandler.java new file mode 100644 index 0000000..95c3362 --- /dev/null +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/OpenHandler.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2010 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + * Lars Vogel - Bug 419770 + *******************************************************************************/ +package com.minres.scviewer.e4.application.handlers; + +import java.io.File; + +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.ui.model.application.MApplication; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.model.application.ui.basic.MPartStack; +import org.eclipse.e4.ui.workbench.modeling.EModelService; +import org.eclipse.e4.ui.workbench.modeling.EPartService; +import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Shell; +public class OpenHandler { + + @Execute + public void execute(Shell shell, MApplication app, EModelService modelService, EPartService partService){ + FileDialog dialog = new FileDialog(shell, SWT.MULTI); + dialog.setFilterExtensions (new String []{"vcd", "txdb", "txlog"}); + dialog.open(); + String path = dialog.getFilterPath(); + for(String fileName: dialog.getFileNames()){ + File file = new File(path+File.separator+fileName); + if(file.exists()){ +// MPart part = MBasicFactory.INSTANCE.createPart(); +// part.setLabel(fileName); +// part.setContributionURI("bundleclass://com.minres.scviewer.e4.application/"+ +// WaveformViewerPart.class.getName()); + MPart part = partService .createPart("com.minres.scviewer.e4.application.partdescriptor.waveformviewer"); + part.setLabel(fileName); + + + MPartStack partStack = (MPartStack)modelService.find("org.eclipse.editorss", app); + partStack.getChildren().add(part); + partService.showPart(part, PartState.ACTIVATE); +// Object o = part.getObject(); +// if(o instanceof WaveformViewerPart) +// ((WaveformViewerPart)o).setPartInput(file); + IEclipseContext ctx=part.getContext(); + ctx.modify("input", file); + ctx.declareModifiable("input"); + + + } + } + } + +} diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/QuitHandler.java b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/QuitHandler.java new file mode 100644 index 0000000..55b7296 --- /dev/null +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/QuitHandler.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2010 - 2013 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + * Lars Vogel - Bug 419770 + *******************************************************************************/ +package com.minres.scviewer.e4.application.handlers; + +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.ui.workbench.IWorkbench; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.widgets.Shell; + + +public class QuitHandler { + @Execute + public void execute(IWorkbench workbench, Shell shell){ + if (MessageDialog.openConfirm(shell, "Confirmation", + "Do you want to exit?")) { + workbench.close(); + } + } +} diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/SaveHandler.java b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/SaveHandler.java new file mode 100644 index 0000000..fb51ee4 --- /dev/null +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/SaveHandler.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2010 - 2013 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + * Lars Vogel - Bug 419770 + *******************************************************************************/ +package com.minres.scviewer.e4.application.handlers; + +import org.eclipse.e4.core.di.annotations.CanExecute; +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.ui.workbench.modeling.EPartService; + +public class SaveHandler { + + @CanExecute + public boolean canExecute(EPartService partService) { + if (partService != null) { + return !partService.getDirtyParts().isEmpty(); + } + return false; + } + + @Execute + public void execute(EPartService partService) { + partService.saveAll(false); + } +} \ No newline at end of file diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/SelectAllHandler.java b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/SelectAllHandler.java new file mode 100644 index 0000000..78043d7 --- /dev/null +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/SelectAllHandler.java @@ -0,0 +1,13 @@ + +package com.minres.scviewer.e4.application.handlers; + +import org.eclipse.e4.core.di.annotations.Execute; + +public class SelectAllHandler { + + @Execute + public void execute() { + + } + +} \ No newline at end of file diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/ZoomHandler.java b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/ZoomHandler.java new file mode 100644 index 0000000..2b98314 --- /dev/null +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/ZoomHandler.java @@ -0,0 +1,40 @@ + +package com.minres.scviewer.e4.application.handlers; + +import javax.inject.Named; + +import org.eclipse.e4.core.di.annotations.CanExecute; +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.workbench.modeling.EPartService; + +import com.minres.scviewer.e4.application.parts.WaveformViewerPart; + +public class ZoomHandler { + + final static String PARAMTER_ID="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level"; + + @CanExecute + public boolean canExecute(EPartService partService) { + return true; + } + + @Execute + public void execute(@Named(PARAMTER_ID) String level, EPartService partService) { + MPart part = partService.getActivePart(); + Object obj = part.getObject(); + if(obj instanceof WaveformViewerPart){ + WaveformViewerPart waveformViewerPart = (WaveformViewerPart) obj; + int zoomLevel = waveformViewerPart.getZoomLevel(); + if("in".equalsIgnoreCase(level)) + waveformViewerPart.setZoomLevel(zoomLevel-1); + else if("out".equalsIgnoreCase(level)) + waveformViewerPart.setZoomLevel(zoomLevel+1); + else if("fit".equalsIgnoreCase(level)) + waveformViewerPart.setZoomFit(); + } + + } + + +} \ No newline at end of file diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/internal/HeapStatus.java b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/internal/HeapStatus.java new file mode 100644 index 0000000..580c7f8 --- /dev/null +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/internal/HeapStatus.java @@ -0,0 +1,607 @@ +package com.minres.scviewer.e4.application.internal; +import java.lang.reflect.Method; + +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener; +import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Canvas; +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.wb.swt.ResourceManager; + +/** + * The Heap Status control, which shows the heap usage statistics in the window trim. + * + * @since 3.1 + */ +public class HeapStatus extends Composite { + + private boolean armed; + private Image gcImage; + private Image disabledGcImage; + private Color bgCol, usedMemCol, lowMemCol, freeMemCol, topLeftCol, bottomRightCol, sepCol, textCol, markCol, armCol; + private Canvas button; + private IEclipsePreferences prefStore; + private int updateInterval; + private boolean showMax; + private long totalMem; + private long prevTotalMem = -1L; + private long prevUsedMem = -1L; + private boolean hasChanged; + private long usedMem; + private long mark = -1; + // start with 12x12 + private Rectangle imgBounds = new Rectangle(0,0,12,12); + private long maxMem = Long.MAX_VALUE; + private boolean maxMemKnown; + private float lowMemThreshold = 0.05f; + private boolean showLowMemThreshold = true; + private boolean updateTooltip = false; + + protected volatile boolean isInGC = false; + + private final Runnable timer = new Runnable() { + @Override + public void run() { + if (!isDisposed()) { + updateStats(); + if (hasChanged) { + if (updateTooltip) { + updateToolTip(); + } + redraw(); + hasChanged = false; + } + getDisplay().timerExec(updateInterval, this); + } + } + }; + + private final IPreferenceChangeListener prefListener = new IPreferenceChangeListener() { + @Override + public void preferenceChange(PreferenceChangeEvent event) { + if (IHeapStatusConstants.PREF_UPDATE_INTERVAL.equals(event.getKey())) { + setUpdateIntervalInMS(prefStore.getInt(IHeapStatusConstants.PREF_UPDATE_INTERVAL, 100)); + } + else if (IHeapStatusConstants.PREF_SHOW_MAX.equals(event.getKey())) { + showMax = prefStore.getBoolean(IHeapStatusConstants.PREF_SHOW_MAX, true); + } + + } + }; + + /** + * 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 preferences the preference store + */ + public HeapStatus(Composite parent, IEclipsePreferences preferences) { + super(parent, SWT.NONE); + + maxMem = getMaxMem(); + maxMemKnown = maxMem != Long.MAX_VALUE; + + this.prefStore = preferences; + preferences.addPreferenceChangeListener(prefListener); + + setUpdateIntervalInMS(preferences.getInt(IHeapStatusConstants.PREF_UPDATE_INTERVAL, 100)); + showMax = preferences.getBoolean(IHeapStatusConstants.PREF_SHOW_MAX, true); + + button = new Canvas(this, SWT.NONE); + button.setToolTipText("Run Garbage Collection"); + + ImageDescriptor imageDesc = ResourceManager.getPluginImageDescriptor("com.minres.scviewer.e4.application", "icons/trash.png"); //$NON-NLS-1$ + Display display = getDisplay(); + gcImage = imageDesc.createImage(); + if (gcImage != null) { + imgBounds = gcImage.getBounds(); + disabledGcImage = new Image(display, gcImage, SWT.IMAGE_DISABLE); + } + 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); + markCol = textCol = display.getSystemColor(SWT.COLOR_INFO_FOREGROUND); + + createContextMenu(); + + Listener listener = new Listener() { + + @Override + 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 == HeapStatus.this) { + paintComposite(event.gc); + } + else if (event.widget == button) { + paintButton(event.gc); + } + break; + case SWT.MouseUp: + if (event.button == 1) { + if (!isInGC) { + arm(false); + gc(); + } + } + break; + case SWT.MouseDown: + if (event.button == 1) { + if (event.widget == HeapStatus.this) { + setMark(); + } else if (event.widget == button) { + if (!isInGC) + arm(true); + } + } + break; + case SWT.MouseEnter: + HeapStatus.this.updateTooltip = true; + updateToolTip(); + break; + case SWT.MouseExit: + if (event.widget == HeapStatus.this) { + HeapStatus.this.updateTooltip = false; + } else if (event.widget == button) { + arm(false); + } + break; + } + } + + }; + addListener(SWT.Dispose, listener); + addListener(SWT.MouseDown, listener); + addListener(SWT.Paint, listener); + addListener(SWT.Resize, listener); + addListener(SWT.MouseEnter, listener); + addListener(SWT.MouseExit, 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() { + @Override + public void run() { + if (!isDisposed()) { + getDisplay().timerExec(updateInterval, timer); + } + } + }); + } + + @Override + public void setBackground(Color color) { + bgCol = color; + button.redraw(); + button.update(); + } + + @Override + public void setForeground(Color color) { + if (color == null) { + usedMemCol = getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND); + } else { + usedMemCol = color; + } + + button.redraw(); + button.update(); + } + + @Override + public Color getForeground() { + if (usedMemCol != null) { + return usedMemCol; + } + return getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND); + } + + /** + * Returns the maximum memory limit, or Long.MAX_VALUE if the max is not known. + */ + private long getMaxMem() { + long max = Long.MAX_VALUE; + try { + // Must use reflect to allow compilation against JCL/Foundation + Method maxMemMethod = Runtime.class.getMethod("maxMemory", new Class[0]); //$NON-NLS-1$ + Object o = maxMemMethod.invoke(Runtime.getRuntime(), new Object[0]); + if (o instanceof Long) { + max = ((Long) o).longValue(); + } + } + catch (Exception e) { + // ignore if method missing or if there are other failures trying to determine the max + } + return max; + } + + private void setUpdateIntervalInMS(int interval) { + updateInterval = Math.max(100, interval); + } + + private void doDispose() { + prefStore.removePreferenceChangeListener(prefListener); + if (gcImage != null) { + gcImage.dispose(); + } + if (disabledGcImage != null) { + disabledGcImage.dispose(); + } + + if (lowMemCol != null) { + lowMemCol.dispose(); + } + if (freeMemCol != null) { + freeMemCol.dispose(); + } + } + + @Override + public Point computeSize(int wHint, int hHint, boolean changed) { + GC gc = new GC(this); + Point p = gc.textExtent("MMMMMMMMMMMM"); + 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 + 15, height); + } + + private void arm(boolean armed) { + if (this.armed == armed) { + return; + } + this.armed = armed; + button.redraw(); + button.update(); + } + + private void gcRunning(boolean isInGC) { + if (this.isInGC == isInGC) { + return; + } + this.isInGC = isInGC; + button.redraw(); + button.update(); + } + + /** + * Creates the context menu + */ + private void createContextMenu() { + MenuManager menuMgr = new MenuManager(); + menuMgr.setRemoveAllWhenShown(true); + menuMgr.addMenuListener(new IMenuListener() { + @Override + public void menuAboutToShow(IMenuManager menuMgr) { + fillMenu(menuMgr); + } + }); + Menu menu = menuMgr.createContextMenu(this); + setMenu(menu); + } + + private void fillMenu(IMenuManager menuMgr) { + menuMgr.add(new SetMarkAction()); + menuMgr.add(new ClearMarkAction()); + menuMgr.add(new ShowMaxAction()); + menuMgr.add(new CloseHeapStatusAction()); +// if (isKyrsoftViewAvailable()) { +// menuMgr.add(new ShowKyrsoftViewAction()); +// } + } + + /** + * Sets the mark to the current usedMem level. + */ + private void setMark() { + updateStats(); // get up-to-date stats before taking the mark + mark = usedMem; + hasChanged = true; + redraw(); + } + + /** + * Clears the mark. + */ + private void clearMark() { + mark = -1; + hasChanged = true; + redraw(); + } + + private void gc() { + gcRunning(true); + Thread t = new Thread() { + @Override + public void run() { + busyGC(); + getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + if (!isDisposed()) { + gcRunning(false); + } + } + }); + } + }; + t.start(); + } + + private void busyGC() { + for (int i = 0; i < 2; ++i) { + System.gc(); + System.runFinalization(); + } + } + + private void paintButton(GC gc) { + Rectangle rect = button.getClientArea(); + if (isInGC) { + if (disabledGcImage != null) { + int buttonY = (rect.height - imgBounds.height) / 2 + rect.y; + gc.drawImage(disabledGcImage, rect.x, buttonY); + } + return; + } + 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) { + if (showMax && maxMemKnown) { + paintCompositeMaxKnown(gc); + } else { + paintCompositeMaxUnknown(gc); + } + } + + private void paintCompositeMaxUnknown(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 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 + if (bgCol != null) { + 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 s = convertToMegString(usedMem)+" of "+ convertToMegString(totalMem); + Point p = gc.textExtent(s); + int sx = (rect.width - 15 - p.x) / 2 + rect.x + 1; + int sy = (rect.height - 2 - p.y) / 2 + rect.y + 1; + gc.setForeground(textCol); + 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 paintCompositeMaxKnown(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 dx = x + w - bw - 2; // divider x + int sw = w - bw - 3; // status width + int uw = (int) (sw * usedMem / maxMem); // used mem width + int ux = x + 1 + uw; // used mem right edge + int tw = (int) (sw * totalMem / maxMem); // current total mem width + int tx = x + 1 + tw; // current total 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.drawLine(tx, y, tx, 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); + + if (lowMemThreshold != 0 && ((double)(maxMem - usedMem) / (double)maxMem < lowMemThreshold)) { + gc.setBackground(lowMemCol); + } else { + gc.setBackground(usedMemCol); + } + gc.fillRectangle(x + 1, y + 1, uw, h - 2); + + gc.setBackground(freeMemCol); + gc.fillRectangle(ux + 1, y + 1, tx - (ux + 1), h - 2); + + // paint line for low memory threshold + if (showLowMemThreshold && lowMemThreshold != 0) { + gc.setForeground(lowMemCol); + int thresholdX = x + 1 + (int) (sw * (1.0 - lowMemThreshold)); + gc.drawLine(thresholdX, y + 1, thresholdX, y + h - 2); + } + + String s = convertToMegString(usedMem)+" of "+convertToMegString(totalMem); + Point p = gc.textExtent(s); + int sx = (rect.width - 15 - p.x) / 2 + rect.x + 1; + int sy = (rect.height - 2 - p.y) / 2 + rect.y + 1; + gc.setForeground(textCol); + 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 / maxMem) + 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() { + Runtime runtime = Runtime.getRuntime(); + totalMem = runtime.totalMemory(); + long freeMem = runtime.freeMemory(); + usedMem = totalMem - freeMem; + + if (convertToMeg(prevUsedMem) != convertToMeg(usedMem)) { + prevUsedMem = usedMem; + this.hasChanged = true; + } + + if (prevTotalMem != totalMem) { + prevTotalMem = totalMem; + this.hasChanged = true; + } + } + + private void updateToolTip() { + String usedStr = convertToMegString(usedMem); + String totalStr = convertToMegString(totalMem); + String maxStr = maxMemKnown ? convertToMegString(maxMem) : ""; + String markStr = mark == -1 ? "" : convertToMegString(mark); + String toolTip = "Heap size: "+usedStr+" of total: "+totalStr+" max: "+maxStr+" mark: "+markStr; + if (!toolTip.equals(getToolTipText())) { + setToolTipText(toolTip); + } + } + + /** + * Converts the given number of bytes to a printable number of megabytes (rounded up). + */ + private String convertToMegString(long numBytes) { + return new Long(convertToMeg(numBytes)).toString()+"M"; + } + + /** + * Converts the given number of bytes to the corresponding number of megabytes (rounded up). + */ + private long convertToMeg(long numBytes) { + return (numBytes + (512 * 1024)) / (1024 * 1024); + } + + + class SetMarkAction extends Action { + SetMarkAction() { + super("&Set Mark"); + } + + @Override + public void run() { + setMark(); + } + } + + class ClearMarkAction extends Action { + ClearMarkAction() { + super("&Clear Mark"); + } + + @Override + public void run() { + clearMark(); + } + } + + class ShowMaxAction extends Action { + ShowMaxAction() { + super("Show &Max Heap", IAction.AS_CHECK_BOX); + setEnabled(maxMemKnown); + setChecked(showMax); + } + + @Override + public void run() { + prefStore.putBoolean(IHeapStatusConstants.PREF_SHOW_MAX, isChecked()); + redraw(); + } + } + + class CloseHeapStatusAction extends Action{ + + CloseHeapStatusAction(){ + super("&Close"); + } + + @Override + public void run(){ +// WorkbenchWindow wbw = (WorkbenchWindow) PlatformUI.getWorkbench() +// .getActiveWorkbenchWindow(); +// if (wbw != null) { +// wbw.showHeapStatus(false); +// } + System.out.println("NYI"); + } + } + +} + diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/internal/IHeapStatusConstants.java b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/internal/IHeapStatusConstants.java new file mode 100644 index 0000000..c17c256 --- /dev/null +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/internal/IHeapStatusConstants.java @@ -0,0 +1,19 @@ +package com.minres.scviewer.e4.application.internal; +/** + * Preference constants for the heap status. + * + * @since 3.1 + */ +public interface IHeapStatusConstants { + + /** + * Preference key for the update interval (value in milliseconds). + */ + String PREF_UPDATE_INTERVAL = "HeapStatus.updateInterval"; //$NON-NLS-1$ + + /** + * Preference key for whether to show max heap, if available (value is boolean). + */ + String PREF_SHOW_MAX = "HeapStatus.showMax"; //$NON-NLS-1$ + +} diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/internal/StatusBarControl.java b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/internal/StatusBarControl.java new file mode 100644 index 0000000..c1fedad --- /dev/null +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/internal/StatusBarControl.java @@ -0,0 +1,209 @@ +package com.minres.scviewer.e4.application.internal; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.inject.Inject; + +import org.eclipse.core.internal.preferences.BundleDefaultPreferences; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.jobs.IJobChangeEvent; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.core.runtime.jobs.JobChangeAdapter; +import org.eclipse.core.runtime.jobs.ProgressProvider; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.e4.core.di.annotations.Optional; +import org.eclipse.e4.ui.di.UIEventTopic; +import org.eclipse.e4.ui.di.UISynchronize; +import org.eclipse.e4.ui.model.application.ui.menu.MToolControl; +import org.eclipse.e4.ui.workbench.modeling.EModelService; +import org.eclipse.jface.action.StatusLineManager; +import org.eclipse.swt.widgets.Composite; + +public class StatusBarControl { + + public static final String STATUS_UPDATE="StatusUpdate"; + public static final String ZOOM_LEVEL="ZoomLevelUpdate"; + public static final String CURSOR_TIME="CursorPosUpdate"; + + @Inject EModelService modelService; + @Inject @Optional IEclipsePreferences preferences; + private final UISynchronize sync; + + protected StatusLineManager manager; + + private SyncedProgressMonitor monitor; + + @Inject + public StatusBarControl(UISynchronize sync) { + this.sync=sync; + manager = new StatusLineManager(); + manager.update(true); + } + + @PostConstruct + void createWidget(Composite parent, MToolControl toolControl) { + if (toolControl.getElementId().equals("org.eclipse.ui.StatusLine")) { //$NON-NLS-1$ + createStatusLine(parent, toolControl); + } else if (toolControl.getElementId().equals("org.eclipse.ui.HeapStatus")) { //$NON-NLS-1$ + createHeapStatus(parent, toolControl); + } else if (toolControl.getElementId().equals("org.eclipse.ui.ProgressBar")) { //$NON-NLS-1$ + createProgressBar(parent, toolControl); + } + } + + @PreDestroy + void destroy() { + if (manager != null) { + manager.dispose(); + manager = null; + } + } + + /** + * @param parent + * @param toolControl + */ + private void createProgressBar(Composite parent, MToolControl toolControl) { + manager.createControl(parent); + monitor=new SyncedProgressMonitor(manager.getProgressMonitor()); + Job.getJobManager().setProgressProvider(new ProgressProvider() { + @Override + public IProgressMonitor createMonitor(Job job) { + return monitor.addJob(job); + } + }); + } + + /** + * @param parent + * @param toolControl + */ + private void createHeapStatus(Composite parent, MToolControl toolControl) { + if(preferences==null){ + preferences=new BundleDefaultPreferences(); + preferences.putInt(IHeapStatusConstants.PREF_UPDATE_INTERVAL, 100); + preferences.putBoolean(IHeapStatusConstants.PREF_SHOW_MAX, true); + } + new HeapStatus(parent, preferences); + } + + /** + * @param parent + * @param toolControl + */ + private void createStatusLine(Composite parent, MToolControl toolControl) { + // IEclipseContext context = modelService.getContainingContext(toolControl); + manager.createControl(parent); + } + + @Inject @Optional + public void getStatusEvent(@UIEventTopic(STATUS_UPDATE) String text) { + if(manager!=null ){ + manager.setMessage(text); + } + } + + private final class SyncedProgressMonitor implements IProgressMonitor { + + IProgressMonitor delegate; + private boolean cancelled; + + SyncedProgressMonitor(IProgressMonitor delegate){ + this.delegate=delegate; + } + + public IProgressMonitor addJob(Job job){ + if(job != null){ + job.addJobChangeListener(new JobChangeAdapter() { + @Override + public void done(IJobChangeEvent event) { + // clean-up + event.getJob().removeJobChangeListener(this); + } + }); + } + return this; + } + + @Override + public void beginTask(final String name, final int totalWork) { + sync.syncExec(new Runnable() { + @Override + public void run() { + delegate.beginTask(name, totalWork); + } + }); + } + + @Override + public void worked(final int work) { + sync.syncExec(new Runnable() { + @Override + public void run() { + delegate.worked(work); + } + }); + } + + @Override + public void done() { + sync.syncExec(new Runnable() { + @Override + public void run() { + delegate.done(); + } + }); + } + + @Override + public void internalWorked(final double work) { + sync.syncExec(new Runnable() { + @Override + public void run() { + delegate.internalWorked(work); + } + }); + } + + @Override + public boolean isCanceled() { + sync.syncExec(new Runnable() { + @Override + public void run() { + cancelled=delegate.isCanceled(); + } + }); + return cancelled; + } + + @Override + public void setCanceled(final boolean value) { + sync.syncExec(new Runnable() { + @Override + public void run() { + delegate.setCanceled(value); + } + }); + } + + @Override + public void setTaskName(final String name) { + sync.syncExec(new Runnable() { + @Override + public void run() { + delegate.setTaskName(name); + } + }); + } + + @Override + public void subTask(final String name) { + sync.syncExec(new Runnable() { + @Override + public void run() { + delegate.subTask(name); + } + }); + } + } +} \ No newline at end of file diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/internal/TrimUtil.java b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/internal/TrimUtil.java new file mode 100644 index 0000000..f67ac3b --- /dev/null +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/internal/TrimUtil.java @@ -0,0 +1,42 @@ +package com.minres.scviewer.e4.application.internal; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; + +/** + * Simple class to provide some common internal Trim support. + * + * @since 3.2 + * + */ +public class TrimUtil { + + /** + * Default height for workbench trim. + */ + public static final int TRIM_DEFAULT_HEIGHT; + static { + Shell s = new Shell(Display.getCurrent(), SWT.NONE); + s.setLayout(new GridLayout()); + ToolBar t = new ToolBar(s, SWT.NONE); + t.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + ToolItem ti = new ToolItem(t, SWT.PUSH); + ti.setImage(JFaceResources.getImageRegistry().get(Dialog.DLG_IMG_MESSAGE_INFO)); + s.layout(); + int toolItemHeight = t.computeSize(SWT.DEFAULT, SWT.DEFAULT).y; + GC gc = new GC(s); + Point fontSize = gc.textExtent("Wg"); //$NON-NLS-1$ + gc.dispose(); + TRIM_DEFAULT_HEIGHT = Math.max(toolItemHeight, fontSize.y); + s.dispose(); + + } +} diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/internal/WaveStatusBarControl.java b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/internal/WaveStatusBarControl.java new file mode 100644 index 0000000..b83196f --- /dev/null +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/internal/WaveStatusBarControl.java @@ -0,0 +1,100 @@ +package com.minres.scviewer.e4.application.internal; + +import java.util.List; + +import javax.inject.Inject; +import javax.inject.Named; + +import org.eclipse.e4.core.di.annotations.Optional; +import org.eclipse.e4.ui.di.UIEventTopic; +import org.eclipse.e4.ui.di.UISynchronize; +import org.eclipse.e4.ui.services.IServiceConstants; +import org.eclipse.e4.ui.workbench.modeling.EModelService; +import org.eclipse.jface.action.ContributionItem; +import org.eclipse.jface.action.StatusLineManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CLabel; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; + +public class WaveStatusBarControl extends StatusBarControl { + + public static final String STATUS_UPDATE="StatusUpdate"; + public static final String ZOOM_LEVEL="ZoomLevelUpdate"; + public static final String CURSOR_TIME="CursorPosUpdate"; + + @Inject + EModelService modelService; + + class TextContributionItem extends ContributionItem { + + final String labelString; + final int width; + CLabel label, text; + private String content; + + public TextContributionItem(String labelString, int width) { + super(); + this.labelString = labelString; + this.width=width; + content=""; + } + + @Override + public void fill(Composite parent) { + Composite box=new Composite(parent, SWT.NONE); + box.setLayout(new GridLayout(2, false)); + label=new CLabel(box, SWT.SHADOW_NONE); + label.setText(labelString); + text=new CLabel(box, SWT.SHADOW_IN); + GridData layoutData=new GridData(SWT.DEFAULT, SWT.DEFAULT, true, false); + layoutData.minimumWidth=width; + text.setLayoutData(layoutData); + } + + @Override + public boolean isDynamic() { + return true; + } + + public void setText(String message){ + this.content=message; + if(text!=null && !text.isDisposed()) text.setText(content); + } + + } + + TextContributionItem zoomContribution, cursorContribution; + + @Inject + public WaveStatusBarControl(UISynchronize sync) { + super(sync); + zoomContribution = new TextContributionItem("Z:", 150); + cursorContribution = new TextContributionItem("C:", 120); + manager.appendToGroup(StatusLineManager.BEGIN_GROUP,cursorContribution); + manager.appendToGroup(StatusLineManager.MIDDLE_GROUP, zoomContribution); + } + + @Inject + public void setSelection(@Named(IServiceConstants.ACTIVE_SELECTION)@Optional Object obj){ + // if(status!=null ) status.setText(obj==null?"":obj.toString()); + if(manager!=null ){ + if(obj instanceof List){ + manager.setMessage(""+((List)obj).size()+" Elements"); + } else + manager.setMessage(obj==null?"":obj.getClass().getSimpleName()+" selected"); + } + } + + @Inject @Optional + public void getZoomEvent(@UIEventTopic(ZOOM_LEVEL) String text) { + zoomContribution.setText(text); + } + + @Inject @Optional + public void getCursorEvent(@UIEventTopic(CURSOR_TIME) String text) { + cursorContribution.setText(text); + } + +} \ No newline at end of file diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/parts/DesignBrowser.java b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/parts/DesignBrowser.java new file mode 100644 index 0000000..dad8f31 --- /dev/null +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/parts/DesignBrowser.java @@ -0,0 +1,108 @@ +package com.minres.scviewer.e4.application.parts; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.Arrays; +import java.util.List; + +import javax.annotation.PostConstruct; +import javax.inject.Inject; + +import org.eclipse.e4.core.di.annotations.Optional; +import org.eclipse.e4.core.services.events.IEventBroker; +import org.eclipse.e4.ui.di.Focus; +import org.eclipse.e4.ui.di.UIEventTopic; +import org.eclipse.e4.ui.workbench.modeling.ESelectionService; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; + +import com.minres.scviewer.database.IWaveformDb; +import com.minres.scviewer.e4.application.provider.TxDbContentProvider; +import com.minres.scviewer.e4.application.provider.TxDbLabelProvider; + +public class DesignBrowser implements ISelectionChangedListener { + + @Inject IEventBroker eventBroker; + + @Inject ESelectionService selectionService; + + private TreeViewer contentOutlineViewer; + + private PropertyChangeListener l = new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if("CHILDS".equals(evt.getPropertyName())){ + contentOutlineViewer.getTree().getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + contentOutlineViewer.refresh(); + } + }); + } + } + }; + + @PostConstruct + public void createComposite(Composite parent) { + parent.setLayout(new GridLayout(1, false)); + contentOutlineViewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); + contentOutlineViewer.addSelectionChangedListener(this); + contentOutlineViewer.getTree().setLayoutData(new GridData(GridData.FILL_BOTH)); + contentOutlineViewer.setContentProvider(new TxDbContentProvider()); + contentOutlineViewer.setLabelProvider(new TxDbLabelProvider()); + contentOutlineViewer.setUseHashlookup(true); + } + + @Focus + public void setFocus() { + contentOutlineViewer.getTree().setFocus(); + setSelection(contentOutlineViewer.getSelection()); + } + + @Override + public void selectionChanged(SelectionChangedEvent event) { + setSelection(event.getSelection()); + } + + protected void setSelection(ISelection iSelection) { + IStructuredSelection selection = (IStructuredSelection)iSelection; + switch(selection.size()){ + case 0: + eventBroker.post(WaveformViewerPart.ACTIVE_NODE, null); + break; + case 1: + eventBroker.post(WaveformViewerPart.ACTIVE_NODE, selection.getFirstElement()); + selectionService.setSelection(selection.getFirstElement()); + break; + default: + eventBroker.post(WaveformViewerPart.ACTIVE_NODE, selection.getFirstElement()); + selectionService.setSelection(selection.toList()); + break; + } + } + + @SuppressWarnings("unchecked") + @Inject @Optional + public void getStatusEvent(@UIEventTopic(WaveformViewerPart.ACTIVE_DATABASE) IWaveformDb database) { + Object input = contentOutlineViewer.getInput(); + if(input!=null && input instanceof List) + ((List)input).get(0).removePropertyChangeListener(l); + contentOutlineViewer.setInput(Arrays.asList(new IWaveformDb[]{database})); + // Set up the tree viewer + database.addPropertyChangeListener(l); + } +/* + * TODO: needs top be implemented + @Inject @Optional + public void getStatusEvent(@UIEventTopic(WaveformViewerPart.ACTIVE_NODE_PATH) String path) { + + } +*/ +}; \ No newline at end of file diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/parts/TransactionDetails.java b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/parts/TransactionDetails.java new file mode 100644 index 0000000..ccdb2a0 --- /dev/null +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/parts/TransactionDetails.java @@ -0,0 +1,233 @@ +package com.minres.scviewer.e4.application.parts; + +import javax.annotation.PostConstruct; +import javax.inject.Inject; +import javax.inject.Named; + +import org.eclipse.e4.core.di.annotations.Optional; +import org.eclipse.e4.core.services.events.IEventBroker; +import org.eclipse.e4.ui.di.Focus; +import org.eclipse.e4.ui.services.IServiceConstants; +import org.eclipse.e4.ui.workbench.modeling.ESelectionService; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ControlAdapter; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.Text; + +import com.minres.scviewer.database.ITx; +import com.minres.scviewer.database.ITxAttribute; +import com.minres.scviewer.e4.application.provider.TxPropertiesContentProvider; +import com.minres.scviewer.e4.application.provider.TxPropertiesLabelProvider; + +public class TransactionDetails { + + // Column constants + public static final int COLUMN_FIRST = 0; + + public static final int COLUMN_SECOND = 1; + + @Inject IEventBroker eventBroker; + + @Inject ESelectionService selectionService; + + private Text nameFilter; + private TableViewer txTableViewer; + private TableColumn col1, col2; + TxAttributeFilter attributeFilter; + + + @PostConstruct + public void createComposite(final Composite parent) { + parent.setLayout(new GridLayout(1, false)); + + nameFilter = new Text(parent, SWT.BORDER); + nameFilter.setMessage("Enter text to filter"); + nameFilter.addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + attributeFilter.setSearchText(((Text) e.widget).getText()); + txTableViewer.refresh(); + } + }); + nameFilter.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + attributeFilter = new TxAttributeFilter(); + + txTableViewer = new TableViewer(parent); + txTableViewer.setContentProvider(new TxPropertiesContentProvider()); + txTableViewer.setLabelProvider(new TxPropertiesLabelProvider()); + txTableViewer.getTable().setLayoutData(new GridData(GridData.FILL_BOTH)); + txTableViewer.addFilter(attributeFilter); + + // Set up the table + Table table = txTableViewer.getTable(); + table.setLayoutData(new GridData(GridData.FILL_BOTH)); + + // Add the first name column + col1 = new TableColumn(table, SWT.LEFT); + col1.setText("Name"); + col1.setResizable(true); + col1.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent event) { + ((TxAttributeViewerSorter) txTableViewer.getSorter()).doSort(COLUMN_FIRST); + txTableViewer.refresh(); + } + }); + + // Add the last name column + col2 = new TableColumn(table, SWT.LEFT); + col2.setText("Value"); + col2.setResizable(true); + col2.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent event) { + ((TxAttributeViewerSorter) txTableViewer.getSorter()).doSort(COLUMN_SECOND); + txTableViewer.refresh(); + } + }); + + // Pack the columns + for (int i = 0, n = table.getColumnCount(); i < n; i++) { + table.getColumn(i).pack(); + } + + // Turn on the header and the lines + table.setHeaderVisible(true); + table.setLinesVisible(true); + + parent.addControlListener(new ControlAdapter() { + public void controlResized(ControlEvent e) { + Table table = txTableViewer.getTable(); + Rectangle area = parent.getClientArea(); + Point preferredSize = table.computeSize(SWT.DEFAULT, SWT.DEFAULT); + int width = area.width - 2*table.getBorderWidth(); + if (preferredSize.y > area.height + table.getHeaderHeight()) { + // Subtract the scrollbar width from the total column width + // if a vertical scrollbar will be required + Point vBarSize = table.getVerticalBar().getSize(); + width -= vBarSize.x; + } + Point oldSize = table.getSize(); + if (oldSize.x > area.width) { + // table is getting smaller so make the columns + // smaller first and then resize the table to + // match the client area width + col1.setWidth(width/3); + col2.setWidth(width - col1.getWidth()); + table.setSize(area.width, area.height); + } else { + // table is getting bigger so make the table + // bigger first and then make the columns wider + // to match the client area width + table.setSize(area.width, area.height); + col1.setWidth(width/3); + col2.setWidth(width - col1.getWidth()); + } + } + }); + } + + @Focus + public void setFocus() { + txTableViewer.getTable().setFocus(); + } + + @Inject + public void setSelection(@Named(IServiceConstants.ACTIVE_SELECTION) @Optional Object object){ + if(txTableViewer!=null && !txTableViewer.getTable().isDisposed()) + if(object instanceof ITx){ + txTableViewer.setInput(object); + } else { + txTableViewer.setInput(null); + } + } + + class TxAttributeViewerSorter extends ViewerSorter { + private static final int ASCENDING = 0; + + private static final int DESCENDING = 1; + + private int column; + + private int direction; + + /** + * Does the sort. If it's a different column from the previous sort, do an + * ascending sort. If it's the same column as the last sort, toggle the sort + * direction. + * + * @param column + */ + public void doSort(int column) { + if (column == this.column) { + // Same column as last sort; toggle the direction + direction = 1 - direction; + } else { + // New column; do an ascending sort + this.column = column; + direction = ASCENDING; + } + } + + /** + * Compares the object for sorting + */ + @SuppressWarnings("unchecked") + public int compare(Viewer viewer, Object e1, Object e2) { + int rc = 0; + ITxAttribute p1 = (ITxAttribute) e1; + ITxAttribute p2 = (ITxAttribute) e2; + + // Determine which column and do the appropriate sort + switch (column) { + case COLUMN_FIRST: + rc = getComparator().compare(p1.getName(), p2.getName()); + break; + case COLUMN_SECOND: + rc = getComparator().compare(p1.getValue(), p2.getValue()); + break; + } + + // If descending order, flip the direction + if (direction == DESCENDING) + rc = -rc; + + return rc; + } + } + + public class TxAttributeFilter extends ViewerFilter { + + private String searchString; + + public void setSearchText(String s) { + this.searchString = ".*" + s + ".*"; + } + + @Override + public boolean select(Viewer viewer, Object parentElement, Object element) { + if (searchString == null || searchString.length() == 0) { + return true; + } + ITxAttribute p = (ITxAttribute) element; + if (p.getName().matches(searchString)) { + return true; + } + return false; + } + } +} \ No newline at end of file diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/parts/WaveformListPart.java b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/parts/WaveformListPart.java new file mode 100644 index 0000000..0b5abec --- /dev/null +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/parts/WaveformListPart.java @@ -0,0 +1,170 @@ +package com.minres.scviewer.e4.application.parts; + +import javax.annotation.PostConstruct; +import javax.inject.Inject; +import javax.inject.Named; + +import org.eclipse.e4.core.di.annotations.Optional; +import org.eclipse.e4.core.services.events.IEventBroker; +import org.eclipse.e4.ui.di.Focus; +import org.eclipse.e4.ui.di.UIEventTopic; +import org.eclipse.e4.ui.services.IServiceConstants; +import org.eclipse.e4.ui.workbench.modeling.ESelectionService; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; +import org.eclipse.wb.swt.ResourceManager; + +import com.minres.scviewer.database.ITx; +import com.minres.scviewer.database.IWaveform; +import com.minres.scviewer.e4.application.provider.TxDbContentProvider; +import com.minres.scviewer.e4.application.provider.TxDbLabelProvider; + +public class WaveformListPart implements ISelectionChangedListener { + + @Inject IEventBroker eventBroker; + + @Inject ESelectionService selectionService; + + private Text nameFilter; + private TableViewer txTableViewer; + ToolItem appendItem, insertItem; + WaveformAttributeFilter attributeFilter; + + @PostConstruct + public void createComposite(Composite parent) { + parent.setLayout(new GridLayout(1, false)); + + nameFilter = new Text(parent, SWT.BORDER); + nameFilter.setMessage("Enter text to filter waveforms"); + nameFilter.addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + attributeFilter.setSearchText(((Text) e.widget).getText()); + txTableViewer.refresh(); + } + }); + nameFilter.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + attributeFilter = new WaveformAttributeFilter(); + + txTableViewer = new TableViewer(parent); + txTableViewer.setContentProvider(new TxDbContentProvider()); + txTableViewer.setLabelProvider(new TxDbLabelProvider()); + txTableViewer.getTable().setLayoutData(new GridData(GridData.FILL_BOTH)); + txTableViewer.addSelectionChangedListener(this); + txTableViewer.addFilter(attributeFilter); + + ToolBar toolBar = new ToolBar(parent, SWT.FLAT | SWT.RIGHT); + toolBar.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1)); + toolBar.setBounds(0, 0, 87, 20); + + insertItem = new ToolItem(toolBar, SWT.NONE); + insertItem.setImage(ResourceManager.getPluginImage("com.minres.scviewer.e4.application", "icons/bullet_plus.png")); + insertItem.setText("Insert"); + insertItem.setEnabled(false); + insertItem.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + eventBroker.post(WaveformViewerPart.ADD_WAVEFORM, + ((IStructuredSelection)txTableViewer.getSelection()).toList()); + + } + }); + appendItem = new ToolItem(toolBar, SWT.NONE); + appendItem.setImage(ResourceManager.getPluginImage("com.minres.scviewer.e4.application", "icons/bullet_plus.png")); + appendItem.setText("Append"); + appendItem.setEnabled(false); + appendItem.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + eventBroker.post(WaveformViewerPart.ADD_WAVEFORM, + ((IStructuredSelection)txTableViewer.getSelection()).toList()); + + } + }); + } + + @Focus + public void setFocus() { + txTableViewer.getTable().setFocus(); + setSelection(txTableViewer.getSelection()); + } + + @Inject @Optional + public void getStatusEvent(@UIEventTopic(WaveformViewerPart.ACTIVE_NODE) Object o) { + txTableViewer.setInput(o); + } + + @Override + public void selectionChanged(SelectionChangedEvent event) { + setSelection(event.getSelection()); + } + + protected void setSelection(ISelection iSelection) { + IStructuredSelection selection = (IStructuredSelection)iSelection; + switch(selection.size()){ + case 0: + appendItem.setEnabled(false); + insertItem.setEnabled(false); + break; + case 1: + selectionService.setSelection(selection.getFirstElement()); + appendItem.setEnabled(true); + break; + default: + selectionService.setSelection(selection.toList()); + appendItem.setEnabled(true); + break; + } + } + + @Inject + public void setSelection(@Named(IServiceConstants.ACTIVE_SELECTION) @Optional Object object){ + if(txTableViewer!=null && !insertItem.isDisposed() && !appendItem.isDisposed()) + if(object instanceof ITx && appendItem.isEnabled()){ + insertItem.setEnabled(true); + } else if(object instanceof IWaveform && appendItem.isEnabled()){ + insertItem.setEnabled(true); + } else { + insertItem.setEnabled(false); + } + } + + public class WaveformAttributeFilter extends ViewerFilter { + + private String searchString; + + public void setSearchText(String s) { + this.searchString = ".*" + s + ".*"; + } + + @Override + public boolean select(Viewer viewer, Object parentElement, Object element) { + if (searchString == null || searchString.length() == 0) { + return true; + } + IWaveform p = (IWaveform) element; + if (p.getName().matches(searchString)) { + return true; + } + return false; + } + } + +} \ No newline at end of file diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/parts/WaveformViewerPart.java b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/parts/WaveformViewerPart.java new file mode 100644 index 0000000..ee056a7 --- /dev/null +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/parts/WaveformViewerPart.java @@ -0,0 +1,369 @@ +package com.minres.scviewer.e4.application.parts; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.annotation.PostConstruct; +import javax.inject.Inject; +import javax.inject.Named; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.core.runtime.jobs.IJobChangeEvent; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.core.runtime.jobs.JobChangeAdapter; +import org.eclipse.e4.core.di.annotations.Optional; +import org.eclipse.e4.core.services.events.IEventBroker; +import org.eclipse.e4.ui.di.Focus; +import org.eclipse.e4.ui.di.PersistState; +import org.eclipse.e4.ui.di.UIEventTopic; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.services.EMenuService; +import org.eclipse.e4.ui.workbench.modeling.ESelectionService; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.swt.widgets.Composite; + +import com.minres.scviewer.database.IHierNode; +import com.minres.scviewer.database.ITx; +import com.minres.scviewer.database.IWaveform; +import com.minres.scviewer.database.IWaveformDb; +import com.minres.scviewer.database.IWaveformDbFactory; +import com.minres.scviewer.database.IWaveformEvent; +import com.minres.scviewer.database.swt.GotoDirection; +import com.minres.scviewer.database.swt.TxDisplay; +import com.minres.scviewer.e4.application.internal.StatusBarControl; + +public class WaveformViewerPart { + + public static final String ACTIVE_DATABASE="Active_Database"; + public static final String ACTIVE_NODE="ActiveNode"; + public static final String ACTIVE_NODE_PATH="ActiveNodePath"; + public static final String ADD_WAVEFORM="AddWaveform"; + + protected static final String DATABASE_FILE = "DATABASE_FILE"; + protected static final String SHOWN_WAVEFORM = "SHOWN_WAVEFORM"; + + private final static String[] zoomLevel={ + "1fs", "10fs", "100fs", + "1ps", "10ps", "100ps", + "1ns", "10ns", "100ns", + "1µs", "10µs", "10µs", + "1ms", "10ms", "100ms", "1s"}; + + public static final String ID = "com.minres.scviewer.ui.TxEditorPart"; //$NON-NLS-1$ + + public static final String WAVE_ACTION_ID = "com.minres.scviewer.ui.action.AddToWave"; + + private TxDisplay txDisplay; + + @Inject private IEventBroker eventBroker; + + @Inject EMenuService menuService; + + @Inject ESelectionService selectionService; + + private IWaveformDb database; + + private IHierNode activeNode; + + private Composite myParent; + + ArrayList filesToLoad; + + Map persistedState; + + + @PostConstruct + public void createComposite(MPart part, Composite parent, IWaveformDbFactory dbFactory) { + myParent=parent; + database=dbFactory.getDatabase(); + database.addPropertyChangeListener(new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if("WAVEFORMS".equals(evt.getPropertyName())) { + myParent.getDisplay().syncExec(new Runnable() { + @Override + public void run() { + txDisplay.setMaxTime(database.getMaxTime()); + } + }); + } + } + }); + txDisplay = new TxDisplay(parent); + txDisplay.setMaxTime(0); + txDisplay.addPropertyChangeListener(TxDisplay.CURSOR_PROPERTY, new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + Long time = (Long) evt.getNewValue(); + eventBroker.post(StatusBarControl.CURSOR_TIME, ""+ time/1000000+"ns"); + + } + }); + txDisplay.addSelectionChangedListener(new ISelectionChangedListener() { + @Override + public void selectionChanged(SelectionChangedEvent event) { + if(event.getSelection() instanceof IStructuredSelection) + for(Object o:((IStructuredSelection)event.getSelection()).toList()){ + if(o instanceof ITx || o instanceof IWaveform){ + selectionService.setSelection(o); + return; + } + } + } + }); + filesToLoad=new ArrayList(); + persistedState = part.getPersistedState(); + Integer files = persistedState.containsKey(DATABASE_FILE+"S")?Integer.parseInt(persistedState.get(DATABASE_FILE+"S")):0; + for(int i=0; i0) + loadDatabase(); + eventBroker.post(StatusBarControl.ZOOM_LEVEL, zoomLevel[txDisplay.getZoomLevel()]); + menuService.registerContextMenu(txDisplay.getNameControl(), "com.minres.scviewer.e4.application.popupmenu.namecontext"); + menuService.registerContextMenu(txDisplay.getValueControl(), "com.minres.scviewer.e4.application.popupmenu.namecontext"); + menuService.registerContextMenu(txDisplay.getWaveformControl(), "com.minres.scviewer.e4.application.popupmenu.wavecontext"); + } + + protected void loadDatabase() { + Job job = new Job(" My Job") { + @Override + protected IStatus run( IProgressMonitor monitor) { + // convert to SubMonitor and set total number of work units + SubMonitor subMonitor = SubMonitor.convert(monitor, filesToLoad.size()); + try { + for(File file: filesToLoad){ +// TimeUnit.SECONDS.sleep(20); + database.load(file); + database.addPropertyChangeListener(txDisplay); + subMonitor.worked(1); + if(monitor.isCanceled()) return Status.CANCEL_STATUS; + } + // sleep a second + } catch (Exception e) { + database=null; + e.printStackTrace(); + return Status.CANCEL_STATUS; + } + return Status.OK_STATUS; + } + }; + job.addJobChangeListener(new JobChangeAdapter(){ + @Override + public void done(IJobChangeEvent event) { + if(event.getResult()==Status.OK_STATUS) + myParent.getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + txDisplay.setMaxTime(database.getMaxTime()); + restoreState(); + } + }); + } + }); + job.schedule(0); + } + + @Inject + @Optional + public void setPartInput( @Named( "input" ) Object partInput ) { + if(partInput instanceof File){ + filesToLoad=new ArrayList(); + File file = (File) partInput; + if(file.exists()){ + filesToLoad.add(file); + try { + String ext = getFileExtension(file.getName()); + if("vcd".equals(ext.toLowerCase())){ + if(askIfToLoad(new File(renameFileExtension(file.getCanonicalPath(), "txdb")))){ + filesToLoad.add(new File(renameFileExtension(file.getCanonicalPath(), "txdb"))); + }else if(askIfToLoad(new File(renameFileExtension(file.getCanonicalPath(), "txlog")))){ + filesToLoad.add(new File(renameFileExtension(file.getCanonicalPath(), "txlog"))); + } + } else if("txdb".equals(ext.toLowerCase()) || "txlog".equals(ext.toLowerCase())){ + if(askIfToLoad(new File(renameFileExtension(file.getCanonicalPath(), "vcd")))){ + filesToLoad.add(new File(renameFileExtension(file.getCanonicalPath(), "vcd"))); + } + } + } catch (IOException e) { // silently ignore any error + } + } + if(filesToLoad.size()>0) + loadDatabase(); + } + } + + @Focus + public void setFocus() { + myParent.setFocus(); + updateAll(); + } + + @PersistState + public void saveState(MPart part) { + // save changes + Map persistedState = part.getPersistedState(); + persistedState.put(DATABASE_FILE+"S", Integer.toString(filesToLoad.size())); + Integer index=0; + for(File file:filesToLoad){ + persistedState.put(DATABASE_FILE+index, file.getAbsolutePath()); + index++; + } + if(activeNode!=null) + persistedState.put(ACTIVE_NODE_PATH, activeNode.getFullName()); + persistedState.put(SHOWN_WAVEFORM+"S", Integer.toString(txDisplay.getStreamList().size())); + index=0; + for(IWaveform waveform:txDisplay.getStreamList()){ + persistedState.put(SHOWN_WAVEFORM+index, waveform.getFullName()); + index++; + } + } + + protected void restoreState() { + updateAll(); + String hierName = persistedState.get(ACTIVE_NODE_PATH); + if(hierName!=null) eventBroker.post(ACTIVE_NODE_PATH, hierName); + Integer waves = persistedState.containsKey(SHOWN_WAVEFORM+"S")?Integer.parseInt(persistedState.get(SHOWN_WAVEFORM+"S")):0; + List> res = new LinkedList<>(); + for(int i=0; i waveform = database.getStreamByName(persistedState.get(SHOWN_WAVEFORM+i)); + if(waveform!=null) res.add(waveform); + } + if(res.size()>0) txDisplay.getStreamList().addAll(res); + } + + private void updateAll() { + eventBroker.post(ACTIVE_DATABASE, database); + eventBroker.post(StatusBarControl.ZOOM_LEVEL, zoomLevel[txDisplay.getZoomLevel()]); + eventBroker.post(StatusBarControl.CURSOR_TIME, Long.toString(txDisplay.getCursorTime()/1000000)+"ns"); + } + + @Inject @Optional + public void getActiveNodeEvent(@UIEventTopic(WaveformViewerPart.ACTIVE_NODE) Object o, MPart activePart) { + if(o instanceof IHierNode){ + activeNode=(IHierNode) o; + } + } + + @Inject @Optional + public void getAddWaveformEvent(@UIEventTopic(WaveformViewerPart.ADD_WAVEFORM) Object o) { + Object sel = selectionService.getSelection(); + if(sel instanceof List) + for(Object el:((List)sel)){ + if(el instanceof IWaveform) + addStreamToList((IWaveform) el); + } + else if(sel instanceof IWaveform ) + addStreamToList((IWaveform) sel); + } + +/* + @Inject + public void setWaveform(@Optional @Named( IServiceConstants.ACTIVE_SELECTION) IWaveform waveform, + @Optional @Named( IServiceConstants.ACTIVE_PART) MPart part) { + if (txDisplay!= null && part.getObject()!=this) { + txDisplay.setSelection(waveform==null?new StructuredSelection():new StructuredSelection(waveform)); + } + } +*/ + protected boolean askIfToLoad(File txFile) { + if(txFile.exists() && + MessageDialog.openQuestion(myParent.getDisplay().getActiveShell(), "Database open", + "Would you like to open the adjacent database "+txFile.getName()+" as well?")){ + return true; + } + return false; + } + + protected static String renameFileExtension(String source, String newExt) { + String target; + String currentExt = getFileExtension(source); + if (currentExt.equals("")){ + target=source+"."+newExt; + } else { + target=source.replaceFirst(Pattern.quote("."+currentExt)+"$", Matcher.quoteReplacement("."+newExt)); + } + return target; + } + + protected static String getFileExtension(String f) { + String ext = ""; + int i = f.lastIndexOf('.'); + if (i > 0 && i < f.length() - 1) { + ext = f.substring(i + 1); + } + return ext; + } + + public IWaveformDb getModel() { + return database; + } + public IWaveformDb getDatabase() { + return database; + } + + public void addStreamToList(IWaveform obj){ + txDisplay.getStreamList().add(obj); + } + + public void addStreamsToList(IWaveform[] iWaveforms){ + for(IWaveform stream:iWaveforms) + addStreamToList(stream); + } + + public void removeStreamFromList(IWaveform obj){ + txDisplay.getStreamList().remove(obj); + } + + public void removeStreamsFromList(IWaveform[] iWaveforms){ + for(IWaveform stream:iWaveforms) + removeStreamFromList(stream); + } + + public List> getStreamList(){ + return txDisplay.getStreamList(); + } + + public void moveSelected(int i) { + txDisplay.moveSelected(i); + } + + public void moveSelection(GotoDirection direction) { + txDisplay.moveSelection(direction); + } + + public void moveCursor(GotoDirection direction) { + txDisplay.moveCursor(direction); } + + public void setZoomLevel(Integer level) { + if(level<0) level=0; + if(level>zoomLevel.length-1) level=zoomLevel.length-1; + txDisplay.setZoomLevel(level); + eventBroker.post(StatusBarControl.ZOOM_LEVEL, zoomLevel[txDisplay.getZoomLevel()]); + } + + public void setZoomFit() { + txDisplay.setZoomLevel(6); + eventBroker.post(StatusBarControl.ZOOM_LEVEL, zoomLevel[txDisplay.getZoomLevel()]); + } + + public int getZoomLevel() { + return txDisplay.getZoomLevel(); + } + +} + \ No newline at end of file diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/provider/TxDbContentProvider.java b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/provider/TxDbContentProvider.java new file mode 100644 index 0000000..21a5752 --- /dev/null +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/provider/TxDbContentProvider.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2014, 2015 MINRES Technologies GmbH and others. + * 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: + * MINRES Technologies GmbH - initial API and implementation + *******************************************************************************/ +package com.minres.scviewer.e4.application.provider; + +import java.util.List; + +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +import com.google.common.base.Predicate; +import com.google.common.collect.Collections2; +import com.minres.scviewer.database.IHierNode; +import com.minres.scviewer.database.IWaveform; + +public class TxDbContentProvider implements ITreeContentProvider { + + // private List nodes; + private boolean showNodes=false; + + @Override + public void dispose() { } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + showNodes=!(newInput instanceof IHierNode); + } + + @Override + public Object[] getElements(Object inputElement) { + if(inputElement instanceof IHierNode){ + return Collections2.filter(((IHierNode)inputElement).getChildNodes(), new Predicate(){ + @Override + public boolean apply(IHierNode arg0) { + return (arg0 instanceof IWaveform)!=showNodes; + } + }).toArray(); + }else if(inputElement instanceof List) + return ((List)inputElement).toArray(); + else + return null; + } + + @Override + public Object[] getChildren(Object parentElement) { + return getElements(parentElement); + } + + @Override + public Object getParent(Object element) { + return null; + } + + @Override + public boolean hasChildren(Object element) { + // Object[] obj = getChildren(element); + Object[] obj = getElements(element); + return obj == null ? false : obj.length > 0; + } + +} diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/provider/TxDbLabelProvider.java b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/provider/TxDbLabelProvider.java new file mode 100644 index 0000000..8b821da --- /dev/null +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/provider/TxDbLabelProvider.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2014, 2015 MINRES Technologies GmbH and others. + * 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: + * MINRES Technologies GmbH - initial API and implementation + *******************************************************************************/ +package com.minres.scviewer.e4.application.provider; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.wb.swt.ResourceManager; + +import com.minres.scviewer.database.IHierNode; +import com.minres.scviewer.database.ISignal; +import com.minres.scviewer.database.ITxStream; +import com.minres.scviewer.database.IWaveformDb; + +public class TxDbLabelProvider implements ILabelProvider { + + private List listeners = new ArrayList(); + + private Image database; + private Image stream; + private Image signal; + private Image folder; + + + public TxDbLabelProvider() { + super(); + database=ResourceManager.getPluginImage("com.minres.scviewer.e4.application", "icons/database.png"); + stream=ResourceManager.getPluginImage("com.minres.scviewer.e4.application", "icons/stream.png"); + folder=ResourceManager.getPluginImage("com.minres.scviewer.e4.application", "icons/folder.png"); + signal=ResourceManager.getPluginImage("com.minres.scviewer.e4.application", "icons/signal.png"); + } + + @Override + public void addListener(ILabelProviderListener listener) { + listeners.add(listener); + } + + @Override + public void dispose() { + if(database!=null) database.dispose(); + if(stream!=null) stream.dispose(); + if(folder!=null) folder.dispose(); + if(signal!=null) signal.dispose(); + } + + @Override + public boolean isLabelProperty(Object element, String property) { + return false; + } + + @Override + public void removeListener(ILabelProviderListener listener) { + listeners.remove(listener); + } + + @Override + public Image getImage(Object element) { + if(element instanceof IWaveformDb){ + return database; + }else if(element instanceof ITxStream){ + return stream; + }else if(element instanceof ISignal){ + return signal; + }else if(element instanceof IHierNode){ + return folder; + } else + return null; + } + + @Override + public String getText(Object element) { + return ((IHierNode)element).getName(); + } + +} + + diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/provider/TxPropertiesContentProvider.java b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/provider/TxPropertiesContentProvider.java new file mode 100644 index 0000000..465db5b --- /dev/null +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/provider/TxPropertiesContentProvider.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2014, 2015 MINRES Technologies GmbH and others. + * 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: + * MINRES Technologies GmbH - initial API and implementation + *******************************************************************************/ +package com.minres.scviewer.e4.application.provider; + +import java.util.List; + +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.Viewer; + +import com.google.common.base.Predicate; +import com.google.common.collect.Collections2; +import com.minres.scviewer.database.IHierNode; +import com.minres.scviewer.database.ITx; +import com.minres.scviewer.database.ITxAttribute; + +public class TxPropertiesContentProvider implements IStructuredContentProvider { + + // private List nodes; + private boolean showNodes=false; + + @Override + public void dispose() { } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + showNodes=!(newInput instanceof IHierNode); + } + + @Override + public Object[] getElements(Object inputElement) { + if(inputElement instanceof ITx){ + return Collections2.filter(((ITx)inputElement).getAttributes(), new Predicate(){ + @Override + public boolean apply(ITxAttribute arg0) { + return (arg0 instanceof ITx)!=showNodes; + } + }).toArray(); + }else if(inputElement instanceof List) + return ((List)inputElement).toArray(); + else + return null; + } + +} diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/provider/TxPropertiesLabelProvider.java b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/provider/TxPropertiesLabelProvider.java new file mode 100644 index 0000000..8822b83 --- /dev/null +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/provider/TxPropertiesLabelProvider.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2014, 2015 MINRES Technologies GmbH and others. + * 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: + * MINRES Technologies GmbH - initial API and implementation + *******************************************************************************/ +package com.minres.scviewer.e4.application.provider; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.swt.graphics.Image; + +import com.minres.scviewer.database.ITxAttribute; +import com.minres.scviewer.e4.application.parts.TransactionDetails; + +public class TxPropertiesLabelProvider implements ITableLabelProvider { + + private List listeners = new ArrayList(); + + public TxPropertiesLabelProvider() { + super(); + } + + @Override + public void dispose() { + } + + @Override + public void addListener(ILabelProviderListener listener) { + listeners.add(listener); + } + + @Override + public void removeListener(ILabelProviderListener listener) { + listeners.remove(listener); + } + + @Override + public boolean isLabelProperty(Object element, String property) { + return false; + } + + @Override + public Image getColumnImage(Object element, int columnIndex) { + return null; + } + + @Override + public String getColumnText(Object element, int columnIndex) { + ITxAttribute attribute = (ITxAttribute) element; + String text = ""; + switch (columnIndex) { + case TransactionDetails.COLUMN_FIRST: + text = attribute.getName(); + break; + case TransactionDetails.COLUMN_SECOND: + text = attribute.getValue().toString(); + break; + } + return text; + } + +} + + diff --git a/com.minres.scviewer.e4.application/src/org/eclipse/wb/swt/ResourceManager.java b/com.minres.scviewer.e4.application/src/org/eclipse/wb/swt/ResourceManager.java new file mode 100644 index 0000000..4bfbc6b --- /dev/null +++ b/com.minres.scviewer.e4.application/src/org/eclipse/wb/swt/ResourceManager.java @@ -0,0 +1,415 @@ +/******************************************************************************* + * Copyright (c) 2011 Google, Inc. + * 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: + * Google, Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.wb.swt; + +import java.io.File; +import java.io.InputStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.resource.CompositeImageDescriptor; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.osgi.framework.Bundle; + +/** + * Utility class for managing OS resources associated with SWT/JFace controls such as colors, fonts, images, + * etc. + * + * !!! IMPORTANT !!! Application code must explicitly invoke the dispose() method to release the + * operating system resources managed by cached objects when those objects and OS resources are no longer + * needed (e.g. on application shutdown) + * + * This class may be freely distributed as part of any application or plugin. + *

+ * + * @author scheglov_ke + * @author Dan Rubel + */ +public class ResourceManager extends SWTResourceManager { + //////////////////////////////////////////////////////////////////////////// + // + // Image + // + //////////////////////////////////////////////////////////////////////////// + private static Map m_descriptorImageMap = new HashMap(); + /** + * Returns an {@link ImageDescriptor} stored in the file at the specified path relative to the specified + * class. + * + * @param clazz + * the {@link Class} relative to which to find the image descriptor. + * @param path + * the path to the image file. + * @return the {@link ImageDescriptor} stored in the file at the specified path. + */ + public static ImageDescriptor getImageDescriptor(Class clazz, String path) { + return ImageDescriptor.createFromFile(clazz, path); + } + /** + * Returns an {@link ImageDescriptor} stored in the file at the specified path. + * + * @param path + * the path to the image file. + * @return the {@link ImageDescriptor} stored in the file at the specified path. + */ + public static ImageDescriptor getImageDescriptor(String path) { + try { + return ImageDescriptor.createFromURL(new File(path).toURI().toURL()); + } catch (MalformedURLException e) { + return null; + } + } + /** + * Returns an {@link Image} based on the specified {@link ImageDescriptor}. + * + * @param descriptor + * the {@link ImageDescriptor} for the {@link Image}. + * @return the {@link Image} based on the specified {@link ImageDescriptor}. + */ + public static Image getImage(ImageDescriptor descriptor) { + if (descriptor == null) { + return null; + } + Image image = m_descriptorImageMap.get(descriptor); + if (image == null) { + image = descriptor.createImage(); + m_descriptorImageMap.put(descriptor, image); + } + return image; + } + /** + * Maps images to decorated images. + */ + @SuppressWarnings("unchecked") + private static Map>[] m_decoratedImageMap = new Map[LAST_CORNER_KEY]; + /** + * Returns an {@link Image} composed of a base image decorated by another image. + * + * @param baseImage + * the base {@link Image} that should be decorated. + * @param decorator + * the {@link Image} to decorate the base image. + * @return {@link Image} The resulting decorated image. + */ + public static Image decorateImage(Image baseImage, Image decorator) { + return decorateImage(baseImage, decorator, BOTTOM_RIGHT); + } + /** + * Returns an {@link Image} composed of a base image decorated by another image. + * + * @param baseImage + * the base {@link Image} that should be decorated. + * @param decorator + * the {@link Image} to decorate the base image. + * @param corner + * the corner to place decorator image. + * @return the resulting decorated {@link Image}. + */ + public static Image decorateImage(final Image baseImage, final Image decorator, final int corner) { + if (corner <= 0 || corner >= LAST_CORNER_KEY) { + throw new IllegalArgumentException("Wrong decorate corner"); + } + Map> cornerDecoratedImageMap = m_decoratedImageMap[corner]; + if (cornerDecoratedImageMap == null) { + cornerDecoratedImageMap = new HashMap>(); + m_decoratedImageMap[corner] = cornerDecoratedImageMap; + } + Map decoratedMap = cornerDecoratedImageMap.get(baseImage); + if (decoratedMap == null) { + decoratedMap = new HashMap(); + cornerDecoratedImageMap.put(baseImage, decoratedMap); + } + // + Image result = decoratedMap.get(decorator); + if (result == null) { + final Rectangle bib = baseImage.getBounds(); + final Rectangle dib = decorator.getBounds(); + final Point baseImageSize = new Point(bib.width, bib.height); + CompositeImageDescriptor compositImageDesc = new CompositeImageDescriptor() { + @Override + protected void drawCompositeImage(int width, int height) { + drawImage(baseImage.getImageData(), 0, 0); + if (corner == TOP_LEFT) { + drawImage(decorator.getImageData(), 0, 0); + } else if (corner == TOP_RIGHT) { + drawImage(decorator.getImageData(), bib.width - dib.width, 0); + } else if (corner == BOTTOM_LEFT) { + drawImage(decorator.getImageData(), 0, bib.height - dib.height); + } else if (corner == BOTTOM_RIGHT) { + drawImage(decorator.getImageData(), bib.width - dib.width, bib.height - dib.height); + } + } + @Override + protected Point getSize() { + return baseImageSize; + } + }; + // + result = compositImageDesc.createImage(); + decoratedMap.put(decorator, result); + } + return result; + } + /** + * Dispose all of the cached images. + */ + public static void disposeImages() { + SWTResourceManager.disposeImages(); + // dispose ImageDescriptor images + { + for (Iterator I = m_descriptorImageMap.values().iterator(); I.hasNext();) { + I.next().dispose(); + } + m_descriptorImageMap.clear(); + } + // dispose decorated images + for (int i = 0; i < m_decoratedImageMap.length; i++) { + Map> cornerDecoratedImageMap = m_decoratedImageMap[i]; + if (cornerDecoratedImageMap != null) { + for (Map decoratedMap : cornerDecoratedImageMap.values()) { + for (Image image : decoratedMap.values()) { + image.dispose(); + } + decoratedMap.clear(); + } + cornerDecoratedImageMap.clear(); + } + } + // dispose plugin images + { + for (Iterator I = m_URLImageMap.values().iterator(); I.hasNext();) { + I.next().dispose(); + } + m_URLImageMap.clear(); + } + } + //////////////////////////////////////////////////////////////////////////// + // + // Plugin images support + // + //////////////////////////////////////////////////////////////////////////// + /** + * Maps URL to images. + */ + private static Map m_URLImageMap = new HashMap(); + /** + * Provider for plugin resources, used by WindowBuilder at design time. + */ + public interface PluginResourceProvider { + URL getEntry(String symbolicName, String path); + } + /** + * Instance of {@link PluginResourceProvider}, used by WindowBuilder at design time. + */ + private static PluginResourceProvider m_designTimePluginResourceProvider = null; + /** + * Returns an {@link Image} based on a plugin and file path. + * + * @param plugin + * the plugin {@link Object} containing the image + * @param name + * the path to the image within the plugin + * @return the {@link Image} stored in the file at the specified path + * + * @deprecated Use {@link #getPluginImage(String, String)} instead. + */ + @Deprecated + public static Image getPluginImage(Object plugin, String name) { + try { + URL url = getPluginImageURL(plugin, name); + if (url != null) { + return getPluginImageFromUrl(url); + } + } catch (Throwable e) { + // Ignore any exceptions + } + return null; + } + /** + * Returns an {@link Image} based on a {@link Bundle} and resource entry path. + * + * @param symbolicName + * the symbolic name of the {@link Bundle}. + * @param path + * the path of the resource entry. + * @return the {@link Image} stored in the file at the specified path. + */ + public static Image getPluginImage(String symbolicName, String path) { + try { + URL url = getPluginImageURL(symbolicName, path); + if (url != null) { + return getPluginImageFromUrl(url); + } + } catch (Throwable e) { + // Ignore any exceptions + } + return null; + } + /** + * Returns an {@link Image} based on given {@link URL}. + */ + private static Image getPluginImageFromUrl(URL url) { + try { + try { + String key = url.toExternalForm(); + Image image = m_URLImageMap.get(key); + if (image == null) { + InputStream stream = url.openStream(); + try { + image = getImage(stream); + m_URLImageMap.put(key, image); + } finally { + stream.close(); + } + } + return image; + } catch (Throwable e) { + // Ignore any exceptions + } + } catch (Throwable e) { + // Ignore any exceptions + } + return null; + } + /** + * Returns an {@link ImageDescriptor} based on a plugin and file path. + * + * @param plugin + * the plugin {@link Object} containing the image. + * @param name + * the path to th eimage within the plugin. + * @return the {@link ImageDescriptor} stored in the file at the specified path. + * + * @deprecated Use {@link #getPluginImageDescriptor(String, String)} instead. + */ + @Deprecated + public static ImageDescriptor getPluginImageDescriptor(Object plugin, String name) { + try { + try { + URL url = getPluginImageURL(plugin, name); + return ImageDescriptor.createFromURL(url); + } catch (Throwable e) { + // Ignore any exceptions + } + } catch (Throwable e) { + // Ignore any exceptions + } + return null; + } + /** + * Returns an {@link ImageDescriptor} based on a {@link Bundle} and resource entry path. + * + * @param symbolicName + * the symbolic name of the {@link Bundle}. + * @param path + * the path of the resource entry. + * @return the {@link ImageDescriptor} based on a {@link Bundle} and resource entry path. + */ + public static ImageDescriptor getPluginImageDescriptor(String symbolicName, String path) { + try { + URL url = getPluginImageURL(symbolicName, path); + if (url != null) { + return ImageDescriptor.createFromURL(url); + } + } catch (Throwable e) { + // Ignore any exceptions + } + return null; + } + /** + * Returns an {@link URL} based on a {@link Bundle} and resource entry path. + */ + private static URL getPluginImageURL(String symbolicName, String path) { + // try runtime plugins + { + Bundle bundle = Platform.getBundle(symbolicName); + if (bundle != null) { + return bundle.getEntry(path); + } + } + // try design time provider + if (m_designTimePluginResourceProvider != null) { + return m_designTimePluginResourceProvider.getEntry(symbolicName, path); + } + // no such resource + return null; + } + /** + * Returns an {@link URL} based on a plugin and file path. + * + * @param plugin + * the plugin {@link Object} containing the file path. + * @param name + * the file path. + * @return the {@link URL} representing the file at the specified path. + * @throws Exception + */ + private static URL getPluginImageURL(Object plugin, String name) throws Exception { + // try to work with 'plugin' as with OSGI BundleContext + try { + Class BundleClass = Class.forName("org.osgi.framework.Bundle"); //$NON-NLS-1$ + Class BundleContextClass = Class.forName("org.osgi.framework.BundleContext"); //$NON-NLS-1$ + if (BundleContextClass.isAssignableFrom(plugin.getClass())) { + Method getBundleMethod = BundleContextClass.getMethod("getBundle", new Class[0]); //$NON-NLS-1$ + Object bundle = getBundleMethod.invoke(plugin, new Object[0]); + // + Class PathClass = Class.forName("org.eclipse.core.runtime.Path"); //$NON-NLS-1$ + Constructor pathConstructor = PathClass.getConstructor(new Class[]{String.class}); + Object path = pathConstructor.newInstance(new Object[]{name}); + // + Class IPathClass = Class.forName("org.eclipse.core.runtime.IPath"); //$NON-NLS-1$ + Class PlatformClass = Class.forName("org.eclipse.core.runtime.Platform"); //$NON-NLS-1$ + Method findMethod = PlatformClass.getMethod("find", new Class[]{BundleClass, IPathClass}); //$NON-NLS-1$ + return (URL) findMethod.invoke(null, new Object[]{bundle, path}); + } + } catch (Throwable e) { + // Ignore any exceptions + } + // else work with 'plugin' as with usual Eclipse plugin + { + Class PluginClass = Class.forName("org.eclipse.core.runtime.Plugin"); //$NON-NLS-1$ + if (PluginClass.isAssignableFrom(plugin.getClass())) { + // + Class PathClass = Class.forName("org.eclipse.core.runtime.Path"); //$NON-NLS-1$ + Constructor pathConstructor = PathClass.getConstructor(new Class[]{String.class}); + Object path = pathConstructor.newInstance(new Object[]{name}); + // + Class IPathClass = Class.forName("org.eclipse.core.runtime.IPath"); //$NON-NLS-1$ + Method findMethod = PluginClass.getMethod("find", new Class[]{IPathClass}); //$NON-NLS-1$ + return (URL) findMethod.invoke(plugin, new Object[]{path}); + } + } + return null; + } + //////////////////////////////////////////////////////////////////////////// + // + // General + // + //////////////////////////////////////////////////////////////////////////// + /** + * Dispose of cached objects and their underlying OS resources. This should only be called when the cached + * objects are no longer needed (e.g. on application shutdown). + */ + public static void dispose() { + disposeColors(); + disposeFonts(); + disposeImages(); + } +} \ No newline at end of file diff --git a/com.minres.scviewer.e4.application/src/org/eclipse/wb/swt/SWTResourceManager.java b/com.minres.scviewer.e4.application/src/org/eclipse/wb/swt/SWTResourceManager.java new file mode 100644 index 0000000..53472ad --- /dev/null +++ b/com.minres.scviewer.e4.application/src/org/eclipse/wb/swt/SWTResourceManager.java @@ -0,0 +1,447 @@ +/******************************************************************************* + * Copyright (c) 2014, 2015 MINRES Technologies GmbH and others. + * 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: + * MINRES Technologies GmbH - initial API and implementation + *******************************************************************************/ +package org.eclipse.wb.swt; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Display; + +/** + * Utility class for managing OS resources associated with SWT controls such as colors, fonts, images, etc. + *

+ * !!! IMPORTANT !!! Application code must explicitly invoke the dispose() method to release the + * operating system resources managed by cached objects when those objects and OS resources are no longer + * needed (e.g. on application shutdown) + *

+ * This class may be freely distributed as part of any application or plugin. + *

+ * @author scheglov_ke + * @author Dan Rubel + */ +public class SWTResourceManager { + //////////////////////////////////////////////////////////////////////////// + // + // Color + // + //////////////////////////////////////////////////////////////////////////// + private static Map m_colorMap = new HashMap(); + /** + * Returns the system {@link Color} matching the specific ID. + * + * @param systemColorID + * the ID value for the color + * @return the system {@link Color} matching the specific ID + */ + public static Color getColor(int systemColorID) { + Display display = Display.getCurrent(); + return display.getSystemColor(systemColorID); + } + /** + * Returns a {@link Color} given its red, green and blue component values. + * + * @param r + * the red component of the color + * @param g + * the green component of the color + * @param b + * the blue component of the color + * @return the {@link Color} matching the given red, green and blue component values + */ + public static Color getColor(int r, int g, int b) { + return getColor(new RGB(r, g, b)); + } + /** + * Returns a {@link Color} given its RGB value. + * + * @param rgb + * the {@link RGB} value of the color + * @return the {@link Color} matching the RGB value + */ + public static Color getColor(RGB rgb) { + Color color = m_colorMap.get(rgb); + if (color == null) { + Display display = Display.getCurrent(); + color = new Color(display, rgb); + m_colorMap.put(rgb, color); + } + return color; + } + /** + * Dispose of all the cached {@link Color}'s. + */ + public static void disposeColors() { + for (Color color : m_colorMap.values()) { + color.dispose(); + } + m_colorMap.clear(); + } + //////////////////////////////////////////////////////////////////////////// + // + // Image + // + //////////////////////////////////////////////////////////////////////////// + /** + * Maps image paths to images. + */ + private static Map m_imageMap = new HashMap(); + /** + * Returns an {@link Image} encoded by the specified {@link InputStream}. + * + * @param stream + * the {@link InputStream} encoding the image data + * @return the {@link Image} encoded by the specified input stream + */ + protected static Image getImage(InputStream stream) throws IOException { + try { + Display display = Display.getCurrent(); + ImageData data = new ImageData(stream); + if (data.transparentPixel > 0) { + return new Image(display, data, data.getTransparencyMask()); + } + return new Image(display, data); + } finally { + stream.close(); + } + } + /** + * Returns an {@link Image} stored in the file at the specified path. + * + * @param path + * the path to the image file + * @return the {@link Image} stored in the file at the specified path + */ + public static Image getImage(String path) { + Image image = m_imageMap.get(path); + if (image == null) { + try { + image = getImage(new FileInputStream(path)); + m_imageMap.put(path, image); + } catch (Exception e) { + image = getMissingImage(); + m_imageMap.put(path, image); + } + } + return image; + } + /** + * Returns an {@link Image} stored in the file at the specified path relative to the specified class. + * + * @param clazz + * the {@link Class} relative to which to find the image + * @param path + * the path to the image file, if starts with '/' + * @return the {@link Image} stored in the file at the specified path + */ + public static Image getImage(Class clazz, String path) { + String key = clazz.getName() + '|' + path; + Image image = m_imageMap.get(key); + if (image == null) { + try { + image = getImage(clazz.getResourceAsStream(path)); + m_imageMap.put(key, image); + } catch (Exception e) { + image = getMissingImage(); + m_imageMap.put(key, image); + } + } + return image; + } + private static final int MISSING_IMAGE_SIZE = 10; + /** + * @return the small {@link Image} that can be used as placeholder for missing image. + */ + private static Image getMissingImage() { + Image image = new Image(Display.getCurrent(), MISSING_IMAGE_SIZE, MISSING_IMAGE_SIZE); + // + GC gc = new GC(image); + gc.setBackground(getColor(SWT.COLOR_RED)); + gc.fillRectangle(0, 0, MISSING_IMAGE_SIZE, MISSING_IMAGE_SIZE); + gc.dispose(); + // + return image; + } + /** + * Style constant for placing decorator image in top left corner of base image. + */ + public static final int TOP_LEFT = 1; + /** + * Style constant for placing decorator image in top right corner of base image. + */ + public static final int TOP_RIGHT = 2; + /** + * Style constant for placing decorator image in bottom left corner of base image. + */ + public static final int BOTTOM_LEFT = 3; + /** + * Style constant for placing decorator image in bottom right corner of base image. + */ + public static final int BOTTOM_RIGHT = 4; + /** + * Internal value. + */ + protected static final int LAST_CORNER_KEY = 5; + /** + * Maps images to decorated images. + */ + @SuppressWarnings("unchecked") + private static Map>[] m_decoratedImageMap = new Map[LAST_CORNER_KEY]; + /** + * Returns an {@link Image} composed of a base image decorated by another image. + * + * @param baseImage + * the base {@link Image} that should be decorated + * @param decorator + * the {@link Image} to decorate the base image + * @return {@link Image} The resulting decorated image + */ + public static Image decorateImage(Image baseImage, Image decorator) { + return decorateImage(baseImage, decorator, BOTTOM_RIGHT); + } + /** + * Returns an {@link Image} composed of a base image decorated by another image. + * + * @param baseImage + * the base {@link Image} that should be decorated + * @param decorator + * the {@link Image} to decorate the base image + * @param corner + * the corner to place decorator image + * @return the resulting decorated {@link Image} + */ + public static Image decorateImage(final Image baseImage, final Image decorator, final int corner) { + if (corner <= 0 || corner >= LAST_CORNER_KEY) { + throw new IllegalArgumentException("Wrong decorate corner"); + } + Map> cornerDecoratedImageMap = m_decoratedImageMap[corner]; + if (cornerDecoratedImageMap == null) { + cornerDecoratedImageMap = new HashMap>(); + m_decoratedImageMap[corner] = cornerDecoratedImageMap; + } + Map decoratedMap = cornerDecoratedImageMap.get(baseImage); + if (decoratedMap == null) { + decoratedMap = new HashMap(); + cornerDecoratedImageMap.put(baseImage, decoratedMap); + } + // + Image result = decoratedMap.get(decorator); + if (result == null) { + Rectangle bib = baseImage.getBounds(); + Rectangle dib = decorator.getBounds(); + // + result = new Image(Display.getCurrent(), bib.width, bib.height); + // + GC gc = new GC(result); + gc.drawImage(baseImage, 0, 0); + if (corner == TOP_LEFT) { + gc.drawImage(decorator, 0, 0); + } else if (corner == TOP_RIGHT) { + gc.drawImage(decorator, bib.width - dib.width, 0); + } else if (corner == BOTTOM_LEFT) { + gc.drawImage(decorator, 0, bib.height - dib.height); + } else if (corner == BOTTOM_RIGHT) { + gc.drawImage(decorator, bib.width - dib.width, bib.height - dib.height); + } + gc.dispose(); + // + decoratedMap.put(decorator, result); + } + return result; + } + /** + * Dispose all of the cached {@link Image}'s. + */ + public static void disposeImages() { + // dispose loaded images + { + for (Image image : m_imageMap.values()) { + image.dispose(); + } + m_imageMap.clear(); + } + // dispose decorated images + for (int i = 0; i < m_decoratedImageMap.length; i++) { + Map> cornerDecoratedImageMap = m_decoratedImageMap[i]; + if (cornerDecoratedImageMap != null) { + for (Map decoratedMap : cornerDecoratedImageMap.values()) { + for (Image image : decoratedMap.values()) { + image.dispose(); + } + decoratedMap.clear(); + } + cornerDecoratedImageMap.clear(); + } + } + } + //////////////////////////////////////////////////////////////////////////// + // + // Font + // + //////////////////////////////////////////////////////////////////////////// + /** + * Maps font names to fonts. + */ + private static Map m_fontMap = new HashMap(); + /** + * Maps fonts to their bold versions. + */ + private static Map m_fontToBoldFontMap = new HashMap(); + /** + * Returns a {@link Font} based on its name, height and style. + * + * @param name + * the name of the font + * @param height + * the height of the font + * @param style + * the style of the font + * @return {@link Font} The font matching the name, height and style + */ + public static Font getFont(String name, int height, int style) { + return getFont(name, height, style, false, false); + } + /** + * Returns a {@link Font} based on its name, height and style. Windows-specific strikeout and underline + * flags are also supported. + * + * @param name + * the name of the font + * @param size + * the size of the font + * @param style + * the style of the font + * @param strikeout + * the strikeout flag (warning: Windows only) + * @param underline + * the underline flag (warning: Windows only) + * @return {@link Font} The font matching the name, height, style, strikeout and underline + */ + public static Font getFont(String name, int size, int style, boolean strikeout, boolean underline) { + String fontName = name + '|' + size + '|' + style + '|' + strikeout + '|' + underline; + Font font = m_fontMap.get(fontName); + if (font == null) { + FontData fontData = new FontData(name, size, style); + if (strikeout || underline) { + try { + Class logFontClass = Class.forName("org.eclipse.swt.internal.win32.LOGFONT"); //$NON-NLS-1$ + Object logFont = FontData.class.getField("data").get(fontData); //$NON-NLS-1$ + if (logFont != null && logFontClass != null) { + if (strikeout) { + logFontClass.getField("lfStrikeOut").set(logFont, Byte.valueOf((byte) 1)); //$NON-NLS-1$ + } + if (underline) { + logFontClass.getField("lfUnderline").set(logFont, Byte.valueOf((byte) 1)); //$NON-NLS-1$ + } + } + } catch (Throwable e) { + System.err.println("Unable to set underline or strikeout" + " (probably on a non-Windows platform). " + e); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + font = new Font(Display.getCurrent(), fontData); + m_fontMap.put(fontName, font); + } + return font; + } + /** + * Returns a bold version of the given {@link Font}. + * + * @param baseFont + * the {@link Font} for which a bold version is desired + * @return the bold version of the given {@link Font} + */ + public static Font getBoldFont(Font baseFont) { + Font font = m_fontToBoldFontMap.get(baseFont); + if (font == null) { + FontData fontDatas[] = baseFont.getFontData(); + FontData data = fontDatas[0]; + font = new Font(Display.getCurrent(), data.getName(), data.getHeight(), SWT.BOLD); + m_fontToBoldFontMap.put(baseFont, font); + } + return font; + } + /** + * Dispose all of the cached {@link Font}'s. + */ + public static void disposeFonts() { + // clear fonts + for (Font font : m_fontMap.values()) { + font.dispose(); + } + m_fontMap.clear(); + // clear bold fonts + for (Font font : m_fontToBoldFontMap.values()) { + font.dispose(); + } + m_fontToBoldFontMap.clear(); + } + //////////////////////////////////////////////////////////////////////////// + // + // Cursor + // + //////////////////////////////////////////////////////////////////////////// + /** + * Maps IDs to cursors. + */ + private static Map m_idToCursorMap = new HashMap(); + /** + * Returns the system cursor matching the specific ID. + * + * @param id + * int The ID value for the cursor + * @return Cursor The system cursor matching the specific ID + */ + public static Cursor getCursor(int id) { + Integer key = Integer.valueOf(id); + Cursor cursor = m_idToCursorMap.get(key); + if (cursor == null) { + cursor = new Cursor(Display.getDefault(), id); + m_idToCursorMap.put(key, cursor); + } + return cursor; + } + /** + * Dispose all of the cached cursors. + */ + public static void disposeCursors() { + for (Cursor cursor : m_idToCursorMap.values()) { + cursor.dispose(); + } + m_idToCursorMap.clear(); + } + //////////////////////////////////////////////////////////////////////////// + // + // General + // + //////////////////////////////////////////////////////////////////////////// + /** + * Dispose of cached objects and their underlying OS resources. This should only be called when the cached + * objects are no longer needed (e.g. on application shutdown). + */ + public static void dispose() { + disposeColors(); + disposeImages(); + disposeFonts(); + disposeCursors(); + } +} \ No newline at end of file diff --git a/signal.xcf b/signal.xcf new file mode 100644 index 0000000..c145f8f Binary files /dev/null and b/signal.xcf differ