001: /* uDig - User Friendly Desktop Internet GIS client
002: * http://udig.refractions.net
003: * (C) 2004, Refractions Research Inc.
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation;
008: * version 2.1 of the License.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: */
015: package net.refractions.udig.internal.ui;
016:
017: import java.io.IOException;
018: import java.util.Collection;
019: import java.util.HashSet;
020: import java.util.List;
021: import java.util.Random;
022:
023: import net.refractions.udig.core.internal.ExtensionPointList;
024: import net.refractions.udig.ui.internal.Messages;
025: import net.refractions.udig.ui.preferences.PreferenceConstants;
026:
027: import org.eclipse.core.runtime.CoreException;
028: import org.eclipse.core.runtime.IConfigurationElement;
029: import org.eclipse.jface.dialogs.Dialog;
030: import org.eclipse.jface.dialogs.IDialogConstants;
031: import org.eclipse.jface.preference.IPreferenceStore;
032: import org.eclipse.jface.resource.ImageDescriptor;
033: import org.eclipse.swt.SWT;
034: import org.eclipse.swt.graphics.Font;
035: import org.eclipse.swt.graphics.FontData;
036: import org.eclipse.swt.graphics.Image;
037: import org.eclipse.swt.graphics.Point;
038: import org.eclipse.swt.layout.GridData;
039: import org.eclipse.swt.layout.GridLayout;
040: import org.eclipse.swt.widgets.Button;
041: import org.eclipse.swt.widgets.Composite;
042: import org.eclipse.swt.widgets.Control;
043: import org.eclipse.swt.widgets.Label;
044: import org.eclipse.swt.widgets.Shell;
045: import org.eclipse.swt.widgets.Text;
046: import org.eclipse.ui.plugin.AbstractUIPlugin;
047: import org.osgi.service.prefs.Preferences;
048:
049: /**
050: * Dialog for showing tips from the tip extension point.
051: */
052: public class TipDialog extends Dialog {
053: public final static String PREFERENCE_ID = "net.refractions.udig.ui.tips"; //$NON-NLS-1$
054:
055: public final static String EXTENSION_ID = "net.refractions.udig.ui.tip"; //$NON-NLS-1$
056:
057: private static Tip current;
058:
059: private static Configuration currentConfiguration;
060:
061: private Image image;
062:
063: private Label title;
064:
065: private Text tip;
066:
067: private Button check;
068:
069: private Label imageLabel;
070:
071: protected TipDialog(Shell parentShell) {
072: super (parentShell);
073: setShellStyle(getShellStyle() | SWT.RESIZE | SWT.MAX);
074: }
075:
076: @Override
077: protected void configureShell(Shell newShell) {
078: newShell.setText(Messages.TipDialog_shellText);
079: super .configureShell(newShell);
080: }
081:
082: @Override
083: protected Point getInitialSize() {
084: return new Point(400, 250);
085: }
086:
087: @Override
088: protected Control createDialogArea(Composite parent) {
089: // create a composite with standard margins and spacing
090: Composite composite = (Composite) super
091: .createDialogArea(parent);
092: composite.setLayout(new GridLayout(2, false));
093:
094: imageLabel = new Label(composite, SWT.NONE);
095: imageLabel.setLayoutData(new GridData(SWT.NONE, SWT.NONE,
096: false, false));
097:
098: title = new Label(composite, SWT.NONE);
099: GridData gridData = new GridData(SWT.FILL, SWT.NONE, true,
100: false);
101: gridData.verticalAlignment = SWT.END;
102: title.setLayoutData(gridData);
103:
104: tip = new Text(composite, SWT.WRAP | SWT.READ_ONLY);
105: tip.setBackground(getShell().getDisplay().getSystemColor(
106: SWT.COLOR_WIDGET_BACKGROUND));
107: gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
108: gridData.horizontalSpan = 2;
109: tip.setLayoutData(gridData);
110:
111: updateTip();
112:
113: check = new Button(composite, SWT.CHECK);
114: gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
115: gridData.horizontalSpan = 2;
116: check.setLayoutData(gridData);
117: check.setText(Messages.TipDialog_question);
118: boolean selected;
119: try {
120: IPreferenceStore store = UiPlugin.getDefault()
121: .getPreferenceStore();
122: selected = store
123: .getBoolean(PreferenceConstants.P_SHOW_TIPS);
124: } catch (Exception e) {
125: UiPlugin.log("", e); //$NON-NLS-1$
126: selected = true;
127: }
128: check.setSelection(selected);
129:
130: return composite;
131: }
132:
133: private void updateTip() {
134: if (getCurrentTip().image != null) {
135: this .image = getCurrentTip().image.createImage();
136: imageLabel.setImage(this .image);
137: }
138: title.setText(getCurrentTip().name);
139: FontData[] fontData = getShell().getFont().getFontData();
140: FontData[] newData = new FontData[fontData.length];
141: for (int i = 0; i < fontData.length; i++) {
142: FontData data = fontData[i];
143: newData[i] = new FontData(data.getName(),
144: data.getHeight() + 2, SWT.BOLD);
145: }
146: title.setFont(new Font(getShell().getDisplay(), newData));
147:
148: if (getCurrentTip() != null && getCurrentTip().hint != null)
149: tip.setText(getCurrentTip().hint);
150: }
151:
152: @Override
153: protected void createButtonsForButtonBar(Composite parent) {
154: createButton(parent, IDialogConstants.NEXT_ID,
155: IDialogConstants.NEXT_LABEL, false);
156: createButton(parent, IDialogConstants.CLOSE_ID,
157: IDialogConstants.CLOSE_LABEL, true);
158: }
159:
160: @Override
161: protected void buttonPressed(int buttonId) {
162: if (IDialogConstants.NEXT_ID == buttonId) {
163: next(-1);
164: updateTip();
165: }
166: if (buttonId == IDialogConstants.CLOSE_ID) {
167: IPreferenceStore store = UiPlugin.getDefault()
168: .getPreferenceStore();
169: store.setValue(PreferenceConstants.P_SHOW_TIPS, check
170: .getSelection());
171: okPressed();
172: }
173: }
174:
175: public static boolean hasTips() {
176: return getCurrentTip() != null;
177: }
178:
179: private static Tip getCurrentTip() {
180: if (current == null) {
181: next(-1);
182: }
183: return current;
184: }
185:
186: private static boolean isInCurrentConfiguration(
187: IConfigurationElement elem) {
188: if (currentConfiguration == null) {
189:
190: List<IConfigurationElement> extensions = ExtensionPointList
191: .getExtensionPointList(EXTENSION_ID);
192: IConfigurationElement mostRecent = null;
193: for (IConfigurationElement element : extensions) {
194: if (element.getName().equals("activeConfiguration")) { //$NON-NLS-1$
195: String attribute = element
196: .getAttribute("configurationID"); //$NON-NLS-1$
197: if (attribute != null)
198: mostRecent = element;
199: }
200: }
201: if (mostRecent == null) {
202: currentConfiguration = Configuration.DEFAULT;
203: } else {
204: for (IConfigurationElement element : extensions) {
205: if (mostRecent
206: .getAttribute("configurationID").equals(element.getAttribute("id"))) { //$NON-NLS-1$ //$NON-NLS-2$
207: currentConfiguration = new Configuration(
208: element);
209: break;
210: }
211: }
212: if (currentConfiguration.extensionIDs.size() == 0
213: && currentConfiguration.tipIDs.size() == 0)
214: currentConfiguration = Configuration.DEFAULT;
215:
216: }
217: }
218: if (currentConfiguration == Configuration.DEFAULT) {
219: return true;
220: }
221:
222: return currentConfiguration.tipIDs.contains(elem
223: .getAttribute("id")) //$NON-NLS-1$
224: || currentConfiguration.extensionIDs.contains(elem
225: .getDeclaringExtension().getUniqueIdentifier());
226: }
227:
228: private static void next(int next2) {
229: int next = next2;
230: try {
231: Preferences node = getPreferences();
232: List<IConfigurationElement> extensions = ExtensionPointList
233: .getExtensionPointList(EXTENSION_ID);
234: if (next == -1) {
235: Random r = new Random();
236: next = r.nextInt(extensions.size());
237: }
238: for (int i = next; i < extensions.size(); i++) {
239: IConfigurationElement elem = extensions.get(i);
240: if (isPermittedNext(node, elem)) {
241: node.put(elem.getAttribute("id"), ""); //$NON-NLS-1$ //$NON-NLS-2$
242: current = new Tip(elem);
243: return;
244: }
245: }
246: for (int i = 0; i < next; i++) {
247: IConfigurationElement elem = extensions.get(i);
248: if (isPermittedNext(node, elem)) {
249: node.put(elem.getAttribute("id"), ""); //$NON-NLS-1$ //$NON-NLS-2$
250: current = new Tip(elem);
251: return;
252: }
253: }
254: if (node.keys().length == 0) {
255: current = null;
256: return;
257: }
258: node.clear();
259: next(next);
260: } catch (Exception e) {
261: UiPlugin.log("", e); //$NON-NLS-1$
262: }
263: }
264:
265: private static boolean isPermittedNext(Preferences node,
266: IConfigurationElement elem) {
267: if (!elem.getName().equals("tip")) //$NON-NLS-1$
268: return false;
269: boolean notPreviouslyShown = node.get(
270: elem.getAttribute("id"), null) == null; //$NON-NLS-1$
271: boolean notSameAsCurrent = (current == null || !elem
272: .getAttribute("id") //$NON-NLS-1$
273: .equals(current.id));
274: return notPreviouslyShown && notSameAsCurrent
275: && isInCurrentConfiguration(elem);
276: }
277:
278: public static Preferences getPreferences() throws CoreException,
279: IOException {
280: Preferences userPreferences = UiPlugin.getUserPreferences();
281: Preferences node = userPreferences.node(PREFERENCE_ID);
282: return node;
283: }
284:
285: private static class Configuration {
286: public static final Configuration DEFAULT = new Configuration();
287:
288: Collection<String> tipIDs;
289: Collection<String> extensionIDs;
290:
291: Configuration(IConfigurationElement confElem) {
292: this .tipIDs = new HashSet<String>();
293: this .extensionIDs = new HashSet<String>();
294: IConfigurationElement[] tipRefs = confElem
295: .getChildren("tipRef"); //$NON-NLS-1$
296: for (IConfigurationElement element : tipRefs) {
297: String attribute = element.getAttribute("tipID"); //$NON-NLS-1$
298: if (attribute != null)
299: tipIDs.add(attribute);
300: }
301: IConfigurationElement[] extensionRefs = confElem
302: .getChildren("tipExtensionRef"); //$NON-NLS-1$
303: for (IConfigurationElement element : extensionRefs) {
304: String attribute = element.getAttribute("extensionID"); //$NON-NLS-1$
305: if (attribute != null)
306: extensionIDs.add(attribute);
307: }
308: }
309:
310: Configuration() {
311: // do nothing
312: }
313: }
314:
315: private static class Tip {
316: public String id;
317:
318: ImageDescriptor image;
319:
320: String name;
321:
322: String hint;
323:
324: Tip(IConfigurationElement tipElem) {
325: id = tipElem.getAttribute("id"); //$NON-NLS-1$
326: name = tipElem.getAttribute("name"); //$NON-NLS-1$
327: hint = tipElem.getValue();
328: if (tipElem.getAttribute("icon") != null) { //$NON-NLS-1$
329: image = AbstractUIPlugin.imageDescriptorFromPlugin(
330: tipElem.getNamespaceIdentifier(), tipElem
331: .getAttribute("icon")); //$NON-NLS-1$
332: } else {
333: image = AbstractUIPlugin.imageDescriptorFromPlugin(
334: UiPlugin.ID, "icons/elcl16/light.GIF"); //$NON-NLS-1$
335: }
336: }
337: }
338: }
|