View | Details | Raw Unified | Return to bug 72374 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/jface/dialogs/PopupDialog.java (+1151 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Common Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/cpl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.jface.dialogs;
12
13
import org.eclipse.jface.action.Action;
14
import org.eclipse.jface.action.GroupMarker;
15
import org.eclipse.jface.action.IAction;
16
import org.eclipse.jface.action.IMenuManager;
17
import org.eclipse.jface.action.MenuManager;
18
import org.eclipse.jface.resource.ImageDescriptor;
19
import org.eclipse.jface.util.Geometry;
20
import org.eclipse.swt.SWT;
21
import org.eclipse.swt.events.SelectionAdapter;
22
import org.eclipse.swt.events.SelectionEvent;
23
import org.eclipse.swt.events.ShellAdapter;
24
import org.eclipse.swt.events.ShellEvent;
25
import org.eclipse.swt.graphics.Color;
26
import org.eclipse.swt.graphics.Image;
27
import org.eclipse.swt.graphics.Point;
28
import org.eclipse.swt.graphics.Rectangle;
29
import org.eclipse.swt.layout.GridData;
30
import org.eclipse.swt.layout.GridLayout;
31
import org.eclipse.swt.widgets.Composite;
32
import org.eclipse.swt.widgets.Display;
33
import org.eclipse.swt.widgets.Event;
34
import org.eclipse.swt.widgets.Label;
35
import org.eclipse.swt.widgets.Listener;
36
import org.eclipse.swt.widgets.Menu;
37
import org.eclipse.swt.widgets.Monitor;
38
import org.eclipse.swt.widgets.Shell;
39
import org.eclipse.swt.widgets.ToolBar;
40
import org.eclipse.swt.widgets.ToolItem;
41
import org.eclipse.swt.widgets.Tracker;
42
43
/**
44
 * The <code>PopupDialog</code> is a generic and customizable dialog comprised
45
 * of three components: a header, the dialog's content and a footer. The
46
 * following properties can be set for this dialog:
47
 * 
48
 * <ul>
49
 * 
50
 * <li>Background and Border color: default color is the widget color.</li>
51
 * <li>Shell style: default style for the shell is SWT.NO_TRIM.</li>
52
 * <li>Footer component: If the <code>hasFooter</code> flag is set, the pop
53
 * up dialog will contain a footer component. To fill the footer's content,
54
 * override <code>createFooterContent(Composite)</code>.</li>
55
 * <li>Header component: If the <code>hasHeader</code> flag is set, the pop
56
 * up dialog will contain a header component. To fill the header's content,
57
 * override <code>createHeaderContent(Composite)</code>.</li>
58
 * <li>Move property: Specify if the pop up dialog should be moveable. If the
59
 * <code>isMoveable</code> property is set, a pull down menu with a move
60
 * action will be added to the dialog. You can also set the standard move
61
 * capability by setting the appropriate shell style.</li>
62
 * <li>Resize property: Specify if the pop up dialog should be resizable. If
63
 * the <code>isResizable</code> property is set, a pull down menu with a
64
 * resize action will be added to the dialog. You can also set the standard
65
 * resize capability by setting the appropriate shell style (i.e: SWT.RESIZE).
66
 * </li>
67
 * <li>Allow the user to remember the bounds: Setting this property will add an
68
 * action item to the pull down menu that will allow the user to select whether
69
 * he/she wants to remember the dialog's bounds if they have changed.</li>
70
 * <li>Remember the bounds of the dialog: Set whether the dialog should
71
 * remember its bounds after it is closed. The location of the dialog is
72
 * remembered relative to its parent, or relative to the display if no parent is
73
 * set.</li>
74
 * <li>Remember the properties of the dialog: Set whether the dialog should
75
 * remember its properties (color, style, parent) on close.</li>
76
 * <li>Dialog location: If the pop up dialog's parent component is set,
77
 * pre-defined locations (relative to the parent) can be set: TOP, BOTTOM,
78
 * RIGHT, LEFT, TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT. If no location
79
 * is set, the dialog will be positioned at the center of its parent, or at the
80
 * center of the display if no parent is set.</li>
81
 * <li>Dialog size: If the pop up dialog's size is not set, the default size
82
 * will be computed using <code>SWT.DEFAULT</code>.</li>
83
 * <li>Dialog content: To specify the dialog's content, override
84
 * <code>createDialogContent(Composite)</code>.</li>
85
 * <li>closeCondition: The dialog's close condition can be set to
86
 * <code>closeDialogOnDeactivation</code>. If no close condition set, the
87
 * default is for the pop up dialog to close when its <code>close()</code>
88
 * method is called.</li>
89
 * </ul>
90
 * 
91
 * The default behavior for the pop up dialog is to contain no header and no
92
 * footer, with widget colors for border and background, SWT.NO_TRIM as the
93
 * shell style and no resize or moving capabilities.
94
 * 
95
 */
96
public class PopupDialog {
97
	/**
98
	 * Move action for the dialog.
99
	 */
100
	private class MoveAction extends Action {
101
102
		MoveAction() {
103
			super("Move", IAction.AS_PUSH_BUTTON); //$NON-NLS-1$
104
		}
105
106
		/*
107
		 * (non-Javadoc)
108
		 * 
109
		 * @see org.eclipse.jface.action.IAction#run()
110
		 */
111
		public void run() {
112
			performTrackerAction(SWT.NONE);
113
		}
114
115
	}
116
117
	/**
118
	 * 
119
	 * Remember bounds action for the dialog.
120
	 */
121
	private class RememberBoundsAction extends Action {
122
123
		RememberBoundsAction() {
124
			super("Remember bounds", IAction.AS_CHECK_BOX); //$NON-NLS-1$
125
			setChecked(rememberDialogBounds);
126
		}
127
128
		/*
129
		 * (non-Javadoc)
130
		 * 
131
		 * @see org.eclipse.jface.action.IAction#run()
132
		 */
133
		public void run() {
134
			rememberDialogBounds = isChecked();
135
		}
136
	}
137
138
	/**
139
	 * 
140
	 * Resize action for the dialog.
141
	 */
142
	private class ResizeAction extends Action {
143
144
		ResizeAction() {
145
			super("Resize", IAction.AS_PUSH_BUTTON); //$NON-NLS-1$
146
		}
147
148
		/*
149
		 * @see org.eclipse.jface.action.Action#run()
150
		 */
151
		public void run() {
152
			performTrackerAction(SWT.RESIZE);
153
		}
154
	}
155
156
	/**
157
	 * At the top (middle) of the parent shell.
158
	 */
159
	final public static int TOP = 0;
160
161
	/**
162
	 * At the bottom (middle) of the parent shell.
163
	 */
164
	final public static int BOTTOM = 1;
165
166
	/**
167
	 * At the right (middle) of the parent shell.
168
	 */
169
	final public static int RIGHT = 2;
170
171
	/**
172
	 * At the left (middle) of the parent shell.
173
	 */
174
	final public static int LEFT = 3;
175
176
	/**
177
	 * At the top left of the parent shell.
178
	 */
179
	final public static int TOP_LEFT = 4;
180
181
	/**
182
	 * At the top right of the parent shell.
183
	 */
184
	final public static int TOP_RIGHT = 5;
185
186
	/**
187
	 * At the bottom left of the parent shell.
188
	 */
189
	final public static int BOTTOM_LEFT = 6;
190
191
	/**
192
	 * At the bottom right of the parent shell.
193
	 */
194
	final public static int BOTTOM_RIGHT = 7;
195
196
	// Margin height and width for locations
197
	private final int marginWidth = 5;
198
199
	private final int marginHeight = 5;
200
201
	/**
202
	 * Close the dialong when it is de-activated.
203
	 */
204
	public final static int closeDialogOnDeactivate = 0;
205
206
	/**
207
	 * By default, the dialog has no closing condition.
208
	 */
209
	private int closeCondition = -1;
210
211
	// Flag to remember the dialog properties (color, size, shell style)
212
	private boolean rememberDialogProperties = false;
213
214
	// Flag to remember the bounds of the dialog (size and location)
215
	private boolean rememberDialogBounds = false;
216
217
	// Background and border colors
218
	private Color backGroundColor = null;
219
220
	private Color borderColor = null;
221
222
	// Bounds of the dialog (location relative to the parent, or display if
223
	// parent is null)
224
	protected Point deltaLocation = null;
225
226
	// Current size for the dialog.
227
	protected Point currentSize = null;
228
229
	// The dialog's toolbar for the move and resize capabilities
230
	private ToolBar fToolBar = null;
231
232
	// The dialog's menu manager
233
	private MenuManager fViewMenuManager = null;
234
235
	// The menu's image
236
	private Image menuImage = null;
237
238
	// The dialog's shell
239
	private Shell dialogShell = null;
240
241
	// The dialog's parent shell
242
	private Shell parentShell = null;
243
244
	// The shell's style
245
	private int shellStyle = SWT.NO_TRIM;
246
247
	// Specify whether the dialog should be moveable
248
	private boolean isMoveable = false;
249
250
	// Specify whether the dialog should be resizable
251
	private boolean isResizable = false;
252
253
	// Specify whether the dialog should have a footer component
254
	private boolean hasFooter = false;
255
256
	// Specify whether the dialog should have a header component
257
	private boolean hasHeader = false;
258
259
	// Specify whether the dialog should allow the user to opt
260
	// to remember the dialog's bounds
261
	private boolean showRememberBounds = false;
262
263
	/**
264
	 * Constructs a new instance of <code>PopupInformationDialog</code>. When
265
	 * the dialog is first constructed, it contains no widgets.
266
	 * 
267
	 * @param parent
268
	 *            The parent shell (could be null).
269
	 */
270
	public PopupDialog(Shell parent) {
271
		parentShell = parent;
272
	}
273
274
	/**
275
	 * Constructs a new instance of <code>PopupInformationDialog</code>. When
276
	 * the dialog is first constructed, it contains no widgets.
277
	 * 
278
	 * @param parent
279
	 *            The parent shell. Or null to create a top level shell.
280
	 * @param shellStyle
281
	 *            The shell style.
282
	 */
283
	public PopupDialog(Shell parent, int shellStyle) {
284
		this.shellStyle = shellStyle;
285
		parentShell = parent;
286
	}
287
288
	/**
289
	 * Constructs a new instance of <code>PopupInformationDialog</code>. When
290
	 * the dialog is first constructed, it contains no widgets.
291
	 * 
292
	 * @param parent
293
	 *            The parent shell.
294
	 * @param shellStyle
295
	 *            The shell style.
296
	 * @param backGroundColor
297
	 *            The background color.
298
	 * @param borderColor
299
	 *            The border color.
300
	 */
301
	public PopupDialog(Shell parent, int shellStyle, Color backGroundColor,
302
			Color borderColor) {
303
		this.shellStyle = shellStyle;
304
		parentShell = parent;
305
		this.backGroundColor = backGroundColor;
306
		this.borderColor = borderColor;
307
	}
308
309
	/**
310
	 * Constructs a new instance of <code>PopupInformationDialog</code>. When
311
	 * the dialog is first constructed, it contains no widgets.
312
	 * 
313
	 * @param parent
314
	 *            The parent shell.
315
	 * @param shellStyle
316
	 *            The shell style.
317
	 * @param isMoveable
318
	 *            The move property of the dialog.
319
	 * @param isResizable
320
	 *            The resizable property of the dialog.
321
	 * @param hasFooter
322
	 *            Specify footer component for the dialog.
323
	 * @param hasHeader
324
	 *            Specify header component for the dialog.
325
	 * @param showRememberBounds
326
	 *            Show the remember bounds menu item.
327
	 * @param backGroundColor
328
	 *            Specify the background color for the dialog.
329
	 * @param borderColor
330
	 *            Specify the border color for the dialog.
331
	 */
332
	public PopupDialog(Shell parent, int shellStyle, boolean isMoveable,
333
			boolean isResizable, boolean hasFooter, boolean hasHeader,
334
			boolean showRememberBounds, Color backGroundColor, Color borderColor) {
335
		this.shellStyle = shellStyle;
336
		this.parentShell = parent;
337
		this.isMoveable = isMoveable;
338
		this.isResizable = isResizable;
339
		this.hasFooter = hasFooter;
340
		this.hasHeader = hasHeader;
341
		this.backGroundColor = backGroundColor;
342
		this.borderColor = borderColor;
343
		this.showRememberBounds = showRememberBounds;
344
	}
345
346
	/**
347
	 * Close the dialog.
348
	 * 
349
	 */
350
	public void close() {
351
		close(rememberDialogProperties);
352
	}
353
354
	/**
355
	 * Close the dialog and specify if the current dialog properties should be
356
	 * remembered.
357
	 * 
358
	 * @param rememberDialogProperties
359
	 *            Remember the dialog properties (colors, move/resize
360
	 *            properties, shell style).
361
	 */
362
	public void close(final boolean rememberDialogProperties) {
363
		this.rememberDialogProperties = rememberDialogProperties;
364
365
		// Persist the bounds
366
		if (rememberDialogBounds) {
367
			currentSize = dialogShell.getSize();
368
			deltaLocation = getDeltaLocation(dialogShell.getLocation());
369
		} else {
370
			deltaLocation = null;
371
			currentSize = null;
372
		}
373
374
		// Reset style, colors...
375
		if (!rememberDialogProperties) {
376
			resetDialogSettings();
377
		}
378
379
		// Clean up variables
380
		menuImage.dispose();
381
		menuImage = null;
382
		fToolBar = null;
383
		fViewMenuManager = null;
384
385
		// dispose
386
		dialogShell.dispose();
387
		dialogShell = null;
388
	}
389
390
	/**
391
	 * Uses the Window's default location computation. Overrite to perform
392
	 * specific location calculations.
393
	 */
394
	protected Point computeLocation(Point size) {
395
396
		// If the location has not been set, compute default
397
		if (deltaLocation == null) {
398
			return getDefaultLocation(size);
399
		}
400
401
		Display display = dialogShell.getDisplay();
402
		// getParentShell() could be null
403
		return display.map(parentShell, null, deltaLocation);
404
405
	}
406
407
	/**
408
	 * Compute the size of the dialog.
409
	 * 
410
	 * @return the size of the dialog.
411
	 */
412
	protected Point computeSize() {
413
		if (currentSize == null) {
414
			return dialogShell.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
415
		}
416
		return currentSize;
417
418
	}
419
420
	/**
421
	 * Create the dialog's content.
422
	 * 
423
	 */
424
	protected void createContents() {
425
		menuImage = ImageDescriptor.createFromFile(PopupDialog.class,
426
				"images/view_menu.gif").createImage();//$NON-NLS-1$
427
428
		// Create a border around the outside of the shell.
429
		dialogShell.setBackground(borderColor);
430
		final GridLayout shellLayout = new GridLayout(1, false);
431
		shellLayout.marginHeight = 1;
432
		shellLayout.marginWidth = 1;
433
		dialogShell.setLayout(shellLayout);
434
435
		// To handle closing of shell for example
436
		setCloseCondition();
437
438
		// Create the top-level composite for the dialog
439
		final Composite contents = new Composite(dialogShell, SWT.NONE);
440
		contents.setBackground(backGroundColor);
441
442
		GridLayout layout = new GridLayout();
443
		layout.marginHeight = 1;
444
		layout.marginWidth = 1;
445
		contents.setLayout(layout);
446
		contents.setLayoutData(new GridData(GridData.FILL_BOTH));
447
448
		// Create the header area
449
		createHeaderArea(contents);
450
451
		// Create the dialog content of the pop up
452
		createDialogArea(contents);
453
454
		if (hasFooter) {
455
			// Create the footer content of the pop up
456
			createFooterArea(contents);
457
		}
458
459
	}
460
461
	/**
462
	 * Create the dialog area.
463
	 * 
464
	 * @param parent
465
	 *            The parent composite.
466
	 */
467
	protected void createDialogArea(Composite parent) {
468
		// Create a composite for the dialog area.
469
		final Composite composite = new Composite(parent, SWT.NONE);
470
		final GridLayout compositeLayout = new GridLayout();
471
		compositeLayout.marginHeight = 0;
472
		compositeLayout.marginWidth = 0;
473
		composite.setLayout(compositeLayout);
474
		composite.setLayoutData(new GridData(GridData.FILL_BOTH));
475
		composite.setBackground(parent.getBackground());
476
		// Fill in top part
477
		createDialogContent(parent);
478
	}
479
480
	/**
481
	 * Create the dialog's content. This method should be overriden to fill the
482
	 * dialog's content. The default implementation does not create anything.
483
	 * 
484
	 * @param parent
485
	 *            The parent composite.
486
	 * 
487
	 */
488
	protected void createDialogContent(Composite parent) {
489
		// default implementation does nothing
490
	}
491
492
	/**
493
	 * Create the dialog's menu for the resize, move and remember bounds
494
	 * actions.
495
	 * 
496
	 * @param parent
497
	 *            The parent composite.
498
	 */
499
	private void createDialogMenu(Composite parent) {
500
501
		fToolBar = new ToolBar(parent, SWT.FLAT);
502
		ToolItem viewMenuButton = new ToolItem(fToolBar, SWT.PUSH, 0);
503
504
		fToolBar.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END
505
				| GridData.GRAB_HORIZONTAL | GridData.FILL_HORIZONTAL));
506
		fToolBar.setBackground(parent.getBackground());
507
508
		viewMenuButton.setImage(menuImage);
509
		viewMenuButton.setToolTipText("Menu"); //$NON-NLS-1$
510
		viewMenuButton.addSelectionListener(new SelectionAdapter() {
511
			public void widgetSelected(SelectionEvent e) {
512
				showDialogMenu();
513
			}
514
		});
515
	}
516
517
	/**
518
	 * Creates the footer area for the dialog.
519
	 */
520
	protected void createFooterArea(Composite parent) {
521
		final Composite composite = new Composite(parent, SWT.NONE);
522
		composite.setLayout(new GridLayout());
523
		composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
524
		composite.setBackground(parent.getBackground());
525
		createSeparator(parent);
526
527
		// Fill in bottom part
528
		createFooterContent(parent);
529
	}
530
531
	/**
532
	 * Creates the footer content of the pop up dialog if the
533
	 * <code>hasFooter</code> flag is set to true. Default implementation does
534
	 * nothing. Override this method to specify the content of the footer
535
	 * component.
536
	 * 
537
	 * @param parent
538
	 *            The parent composite.
539
	 */
540
	protected void createFooterContent(Composite parent) {
541
		// default implementation does nothing
542
543
	}
544
545
	/**
546
	 * Create the header aread for the dialog.
547
	 * 
548
	 * @param parent
549
	 *            The parent composite.
550
	 */
551
	protected void createHeaderArea(final Composite parent) {
552
		boolean hasMenu = isResizable || isMoveable;
553
		if (!hasHeader && !(hasMenu)) {
554
			// If the dialog does not have a header and the menu, don't create
555
			// anything
556
			return;
557
		}
558
559
		int numColumns = 1;
560
		if (hasHeader) {
561
			numColumns = 2;
562
		}
563
564
		Composite headerComposite = new Composite(parent, SWT.NONE);
565
		headerComposite.setBackground(parent.getBackground());
566
		GridLayout layout = new GridLayout(numColumns, false);
567
		layout.marginHeight = 0;
568
		layout.marginWidth = 0;
569
		headerComposite.setLayout(layout);
570
		headerComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
571
572
		if (hasHeader) {
573
			// Should be overwritten - does nothing
574
			createHeaderContent(headerComposite);
575
		}
576
		if (hasMenu) {
577
			createDialogMenu(headerComposite);
578
		}
579
580
		createSeparator(parent);
581
	}
582
583
	/**
584
	 * Creates the header content of the pop up dialog if the
585
	 * <code>hasHeader</code> flag is set to true. Default implementation does
586
	 * nothing. Override this method to specify the content of the header
587
	 * component.
588
	 * 
589
	 * @param parent
590
	 *            The parent composite.
591
	 */
592
	protected void createHeaderContent(Composite parent) {
593
		// default implementation does nothing
594
	}
595
596
	/**
597
	 * Create the separator.
598
	 * 
599
	 * @param parent
600
	 *            The parent composite.
601
	 */
602
	private void createSeparator(Composite parent) {
603
		Label separator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL
604
				| SWT.LINE_DOT);
605
		separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
606
	}
607
608
	/**
609
	 * Create the shell for the dialog.
610
	 * 
611
	 */
612
	protected void createShell() {
613
		// Create the shell
614
		dialogShell = new Shell(parentShell, shellStyle);
615
616
		// To handle "ESC" case
617
		dialogShell.addShellListener(new ShellAdapter() {
618
			public void shellClosed(ShellEvent event) {
619
				event.doit = false; // don't close now
620
				close();
621
			}
622
		});
623
624
		GridLayout layout = new GridLayout();
625
		layout.marginHeight = 0;
626
		layout.marginWidth = 0;
627
		dialogShell.setLayout(layout);
628
629
	}
630
631
	/**
632
	 * Fill the dialog's menu.
633
	 * 
634
	 * @param dialogMenu
635
	 *            The dialog's menu.
636
	 */
637
	protected void fillDialogMenu(IMenuManager dialogMenu) {
638
		dialogMenu.add(new GroupMarker("SystemMenuStart")); //$NON-NLS-1$
639
		if (isMoveable) {
640
			dialogMenu.add(new MoveAction());
641
		}
642
		if (isResizable) {
643
			dialogMenu.add(new ResizeAction());
644
		}
645
646
		if (showRememberBounds) {
647
			dialogMenu.add(new RememberBoundsAction());
648
		}
649
	}
650
651
	/**
652
	 * Get the bottom Y coordinate.
653
	 * 
654
	 * @param parentLocation
655
	 *            The parent location.
656
	 * @param parentSize
657
	 *            The parent's size.
658
	 * @return the bottom Y coordinate.
659
	 */
660
	private int getBottomYCoordinate(Point parentLocation, Point parentSize) {
661
		return parentLocation.y + parentSize.y + marginHeight;
662
	}
663
664
	/**
665
	 * Return the computed location.
666
	 * 
667
	 * @param locationType
668
	 *            The location type.
669
	 * @param newSize
670
	 *            The dialog's size.
671
	 * @return the new dialog's location.
672
	 */
673
	private Point getComputedLocation(int locationType, Point newSize) {
674
		Point parentLocation = parentShell.getLocation();
675
		Point parentSize = parentShell.getSize();
676
		Point newLocation = null;
677
		switch (locationType) {
678
		// TOP
679
		case 0:
680
			newLocation = new Point(getMiddleXCoordinate(parentLocation,
681
					parentSize, newSize), getTopYCoordinate(newSize,
682
					parentLocation));
683
684
			break;
685
		// BOTTOM
686
		case 1:
687
			newLocation = new Point(getMiddleXCoordinate(parentLocation,
688
					parentSize, newSize), getBottomYCoordinate(parentLocation,
689
					parentSize));
690
			break;
691
		// RIGHT
692
		case 2:
693
			newLocation = new Point(getRightXCoordinate(parentLocation,
694
					parentSize), getMiddleYCoordinate(newSize, parentLocation,
695
					parentSize));
696
			break;
697
		// LEFT
698
		case 3:
699
			newLocation = new Point(
700
					getLeftXCoordinate(newSize, parentLocation),
701
					getMiddleYCoordinate(newSize, parentLocation, parentSize));
702
			break;
703
		// TOP_LEFT
704
		case 4:
705
			newLocation = new Point(
706
					getLeftXCoordinate(newSize, parentLocation),
707
					getTopYCoordinate(newSize, parentLocation));
708
			break;
709
		// TOP_RIGHT
710
		case 5:
711
			newLocation = new Point(getRightXCoordinate(parentLocation,
712
					parentSize), getTopYCoordinate(newSize, parentLocation));
713
			break;
714
		// BOTTOM_LEFT
715
		case 6:
716
			newLocation = new Point(
717
					getLeftXCoordinate(newSize, parentLocation),
718
					getBottomYCoordinate(parentLocation, parentSize));
719
			break;
720
		// BOTTOM_RIGHT
721
		case 7:
722
			newLocation = new Point(getRightXCoordinate(parentLocation,
723
					parentSize), getBottomYCoordinate(parentLocation,
724
					parentSize));
725
			break;
726
727
		}
728
		return newLocation;
729
	}
730
731
	/**
732
	 * Default location compuation. The default location positions the dialog at
733
	 * the center of its parent, or at the center of the display if the parent
734
	 * has not been set.
735
	 * 
736
	 * @param initialSize
737
	 *            The dialog's size.
738
	 * @return default location.
739
	 */
740
	protected Point getDefaultLocation(Point initialSize) {
741
		Monitor monitor = dialogShell.getDisplay().getPrimaryMonitor();
742
		if (parentShell != null) {
743
			monitor = parentShell.getMonitor();
744
		}
745
746
		Rectangle monitorBounds = monitor.getClientArea();
747
		Point centerPoint;
748
		if (parentShell != null) {
749
			centerPoint = Geometry.centerPoint(parentShell.getBounds());
750
		} else {
751
			centerPoint = Geometry.centerPoint(monitorBounds);
752
		}
753
754
		return new Point(centerPoint.x - (initialSize.x / 2), Math.max(
755
				monitorBounds.y, Math.min(centerPoint.y
756
						- (initialSize.y * 2 / 3), monitorBounds.y
757
						+ monitorBounds.height - initialSize.y)));
758
	}
759
760
	/**
761
	 * Return the location relative to the parent (or the display if parent is
762
	 * null).
763
	 * 
764
	 * @param childLocation
765
	 *            The child's location.
766
	 * @return the location relative to the parent's location.
767
	 */
768
	private Point getDeltaLocation(Point childLocation) {
769
		Display display = null;
770
		if (dialogShell != null) {
771
			display = dialogShell.getDisplay();
772
		} else {
773
			display = Display.getDefault();
774
		}
775
		// parentShell could be null
776
		return display.map(null, parentShell, childLocation);
777
	}
778
779
	/**
780
	 * Get the left X coordinate.
781
	 * 
782
	 * @param newSize
783
	 *            The new size.
784
	 * @param parentLocation
785
	 *            The parent location.
786
	 * @return the left X coordinate.
787
	 */
788
	private int getLeftXCoordinate(Point newSize, Point parentLocation) {
789
		return (parentLocation.x - newSize.x) - marginWidth;
790
	}
791
792
	/**
793
	 * Get the middle X coordinate.
794
	 * 
795
	 * @param parentLocation
796
	 *            The parent location.
797
	 * @param parentSize
798
	 *            The parent size.
799
	 * @param childSize
800
	 *            The child size.
801
	 * @return the middle X coordinate.
802
	 */
803
	private int getMiddleXCoordinate(Point parentLocation, Point parentSize,
804
			Point childSize) {
805
		return parentLocation.x + parentSize.x / 2 - childSize.x / 2;
806
	}
807
808
	/**
809
	 * Get the middle Y coordinate.
810
	 * 
811
	 * @param newSize
812
	 *            The new size.
813
	 * @param parentLocation
814
	 *            The parent location.
815
	 * @param parentSize
816
	 *            The parent's size.
817
	 * @return the middle Y coordinate.
818
	 */
819
	private int getMiddleYCoordinate(Point newSize, Point parentLocation,
820
			Point parentSize) {
821
		return parentLocation.y + parentSize.y / 2 - newSize.y / 2;
822
	}
823
824
	/**
825
	 * Get the right X coordinate.
826
	 * 
827
	 * @param parentLocation
828
	 *            The parent location.
829
	 * @param parentSize
830
	 *            The parent's size.
831
	 * @return the right X coordinate.
832
	 */
833
	private int getRightXCoordinate(Point parentLocation, Point parentSize) {
834
		return parentLocation.x + parentSize.x + marginWidth;
835
	}
836
837
	/**
838
	 * Get the top Y coordinate.
839
	 * 
840
	 * @param size
841
	 *            The dialog's size.
842
	 * @param parentLocation
843
	 *            The parent location.
844
	 * @return the top Y coordinate.
845
	 */
846
	private int getTopYCoordinate(Point size, Point parentLocation) {
847
		return parentLocation.y - size.y - marginHeight;
848
	}
849
850
	/**
851
	 * Initialize the shell's bounds.
852
	 * 
853
	 */
854
	protected void initializeBounds() {
855
		Point size = computeSize();
856
		Point location = computeLocation(size);
857
		dialogShell.setBounds(new Rectangle(location.x, location.y, size.x,
858
				size.y));
859
	}
860
861
	/**
862
	 * Checks whether the dialog is open.
863
	 * 
864
	 * @return returns true if the dialog is open, false otherwise.
865
	 */
866
	public boolean isOpen() {
867
		return dialogShell != null;
868
	}
869
870
	/**
871
	 * Open the pop up dialog.
872
	 * 
873
	 */
874
	public void open() {
875
		// If the dialog is already open, dispose the shell and recreate it
876
		if (dialogShell != null) {
877
			close();
878
		}
879
880
		// create shell
881
		createShell();
882
		createContents();
883
		initializeBounds();
884
885
		// open the window
886
		dialogShell.open();
887
	}
888
889
	/**
890
	 * Perform the requested tracker action (resize or move).
891
	 * 
892
	 * @param style
893
	 *            The track style (resize or move).
894
	 */
895
	private void performTrackerAction(int style) {
896
		Tracker tracker = new Tracker(dialogShell.getDisplay(), style);
897
		tracker.setStippled(true);
898
		Rectangle[] r = new Rectangle[] { dialogShell.getBounds() };
899
		tracker.setRectangles(r);
900
901
		if (tracker.open()) {
902
			dialogShell.setBounds(tracker.getRectangles()[0]);
903
904
		}
905
	}
906
907
	/**
908
	 * Clear the shell settings.
909
	 * 
910
	 */
911
	protected void resetDialogSettings() {
912
		// Reset values
913
		backGroundColor = null;
914
		borderColor = null;
915
		closeCondition = -1;
916
		rememberDialogProperties = false;
917
		shellStyle = SWT.NO_TRIM;
918
		isMoveable = true;
919
		isResizable = true;
920
		hasFooter = true;
921
		hasHeader = true;
922
		parentShell = null;
923
		showRememberBounds = false;
924
	}
925
926
	/**
927
	 * Set the background color of the dialog.
928
	 * 
929
	 * @param color
930
	 *            The color.
931
	 */
932
	public void setBackGroundColor(Color color) {
933
		backGroundColor = color;
934
	}
935
936
	/**
937
	 * Set the border color of the dialog.
938
	 * 
939
	 * @param color
940
	 *            The color.
941
	 */
942
	public void setBorderColor(Color color) {
943
		borderColor = color;
944
	}
945
946
	/**
947
	 * Set the closing condition for the dialog.
948
	 * 
949
	 */
950
	protected void setCloseCondition() {
951
		switch (closeCondition) {
952
		case closeDialogOnDeactivate:
953
			dialogShell.addListener(SWT.Deactivate, new Listener() {
954
				public void handleEvent(Event event) {
955
					dialogShell.removeListener(SWT.Deactivate, this);
956
					close();
957
				}
958
			});
959
			break;
960
		default:
961
		}
962
963
	}
964
965
	/**
966
	 * Set the dialog's closing condition.
967
	 * 
968
	 * @param closingStyle
969
	 *            The closing style.
970
	 */
971
	public void setCloseCondition(int closingStyle) {
972
		this.closeCondition = closingStyle;
973
	}
974
975
	/**
976
	 * Specify if the pop up dialog has a footer component.
977
	 * 
978
	 * @param hasFooter
979
	 *            Footer component flag.
980
	 */
981
	public void setHasFooter(boolean hasFooter) {
982
		this.hasFooter = hasFooter;
983
	}
984
985
	/**
986
	 * Specifiy if the pop up dialog has a header component.
987
	 * 
988
	 * @param hasHeader
989
	 *            Header component flag.
990
	 */
991
	public void setHasHeader(boolean hasHeader) {
992
		this.hasHeader = hasHeader;
993
	}
994
995
	/**
996
	 * Specify if the dialog is moveable. If the flag is set to true, a pull
997
	 * down menu is added to the top right corner of the dialog to provide that
998
	 * functionality. To allow the move functionality without having the pull
999
	 * down menu, just specify the appropriate shell style.
1000
	 * 
1001
	 * @param isMoveable
1002
	 *            Moveable flag.
1003
	 */
1004
	public void setIsMoveable(boolean isMoveable) {
1005
		this.isMoveable = isMoveable;
1006
	}
1007
1008
	/**
1009
	 * Specify if the dialog is resizable. If the flag is set to true, a pull
1010
	 * down menu is added to the top right corner of the dialog to provide that
1011
	 * functionality. To allow the resize functionality without having the pull
1012
	 * down menu, just specify the appropriate shell style (i.e.:
1013
	 * <code>setShellStyle(SWT.RESIZE)</code>).
1014
	 * 
1015
	 * @param isResizable
1016
	 *            Resizable flag.
1017
	 */
1018
	public void setIsResizable(boolean isResizable) {
1019
		this.isResizable = isResizable;
1020
1021
	}
1022
1023
	/**
1024
	 * Set the diaog's location.
1025
	 * 
1026
	 * @param x
1027
	 *            The width.
1028
	 * @param y
1029
	 *            The height.
1030
	 */
1031
	public void setLocation(int x, int y) {
1032
		// Store the location relative to its parent
1033
		deltaLocation = getDeltaLocation(new Point(x, y));
1034
	}
1035
1036
	/**
1037
	 * Set the location of the dialog. The location type is relative to the
1038
	 * parent, hence, the parent shell cannot be null.
1039
	 * 
1040
	 * @param locationType
1041
	 *            The location type.
1042
	 * @param newSize
1043
	 *            The size of the dialog.
1044
	 */
1045
	public void setLocation(int locationType, Point newSize) {
1046
		Point newLocation = getComputedLocation(locationType, newSize);
1047
		if (newLocation != null) {
1048
			deltaLocation = getDeltaLocation(newLocation);
1049
			this.currentSize = newSize;
1050
		}
1051
1052
	}
1053
1054
	/**
1055
	 * Set the location.
1056
	 * 
1057
	 * @param childLocation
1058
	 *            The child location.
1059
	 */
1060
	public void setLocation(Point childLocation) {
1061
		// Store the location relative to its parent
1062
		deltaLocation = getDeltaLocation(childLocation);
1063
	}
1064
1065
	/**
1066
	 * Specify if the pop up dialog should remember its bounds (size and
1067
	 * location) on close.
1068
	 * 
1069
	 * @param rememberBounds
1070
	 *            Remember bounds flag.
1071
	 */
1072
	public void setRememberDialogBounds(boolean rememberBounds) {
1073
		this.rememberDialogBounds = rememberBounds;
1074
	}
1075
1076
	/**
1077
	 * Specify if the pop up diaog should remember its properties (colors, shell
1078
	 * style, closing style...) on close.
1079
	 * 
1080
	 * @param rememberProperties
1081
	 *            Remember properties flag.
1082
	 */
1083
	public void setRememberDialogProperties(boolean rememberProperties) {
1084
		this.rememberDialogProperties = rememberProperties;
1085
	}
1086
1087
	/**
1088
	 * Set the shell's style.
1089
	 * 
1090
	 * @param newShellStyle
1091
	 *            The shell style.
1092
	 */
1093
	public void setShellStyle(int newShellStyle) {
1094
		this.shellStyle = newShellStyle;
1095
	}
1096
1097
	/**
1098
	 * Set whether the dialog should allow the user to chose to save or discard
1099
	 * the pop up's bounds through a menu item.
1100
	 * 
1101
	 * @param showRememberBounds
1102
	 *            Flag to show the remember bounds menu item.
1103
	 */
1104
	public void setShowRememberBounds(boolean showRememberBounds) {
1105
		this.showRememberBounds = showRememberBounds;
1106
	}
1107
1108
	/**
1109
	 * Set the dialog's size.
1110
	 * 
1111
	 * @param x
1112
	 *            The width.
1113
	 * @param y
1114
	 *            The height.
1115
	 */
1116
	public void setSize(int x, int y) {
1117
		if (currentSize == null) {
1118
			currentSize = new Point(x, y);
1119
		} else {
1120
			currentSize.x = x;
1121
			currentSize.y = y;
1122
		}
1123
	}
1124
1125
	/**
1126
	 * Set the size of the dialog.
1127
	 * 
1128
	 * @param point
1129
	 *            The dialog's size.
1130
	 */
1131
	public void setSize(Point point) {
1132
		currentSize = point;
1133
1134
	}
1135
1136
	/**
1137
	 * Show the dialog's menu.
1138
	 * 
1139
	 */
1140
	private void showDialogMenu() {
1141
		fViewMenuManager = new MenuManager();
1142
		fillDialogMenu(fViewMenuManager);
1143
		Menu aMenu = fViewMenuManager.createContextMenu(dialogShell);
1144
		Rectangle bounds = fToolBar.getBounds();
1145
		Point topLeft = new Point(bounds.x, bounds.y + bounds.height);
1146
		topLeft = dialogShell.toDisplay(topLeft);
1147
		aMenu.setLocation(topLeft.x, topLeft.y);
1148
		aMenu.setVisible(true);
1149
	}
1150
1151
}
(-)src/org/eclipse/jface/dialogs/images/view_menu.gif (+1 lines)
Added Link Here
1
GIF89a¢o/iŸ=t¤Sˆ^‘°N‘³xµÂÿÿÿ!ù,xºÜþ0ÊIk#ë  FHt—P¤éÔZp,ÏK;

Return to bug 72374