Source code: com/port80/swt/apps/ImageViewer1.java
1 package com.port80.swt.apps;
2
3 import java.io.InputStream;
4 import java.net.URL;
5 import java.text.MessageFormat;
6
7 import org.eclipse.swt.SWT;
8 import org.eclipse.swt.SWTException;
9 import org.eclipse.swt.custom.StyledText;
10 import org.eclipse.swt.events.ControlAdapter;
11 import org.eclipse.swt.events.ControlEvent;
12 import org.eclipse.swt.events.DisposeEvent;
13 import org.eclipse.swt.events.DisposeListener;
14 import org.eclipse.swt.events.MouseEvent;
15 import org.eclipse.swt.events.MouseMoveListener;
16 import org.eclipse.swt.events.PaintEvent;
17 import org.eclipse.swt.events.PaintListener;
18 import org.eclipse.swt.events.SelectionAdapter;
19 import org.eclipse.swt.events.SelectionEvent;
20 import org.eclipse.swt.events.ShellAdapter;
21 import org.eclipse.swt.events.ShellEvent;
22 import org.eclipse.swt.graphics.Color;
23 import org.eclipse.swt.graphics.Cursor;
24 import org.eclipse.swt.graphics.Font;
25 import org.eclipse.swt.graphics.GC;
26 import org.eclipse.swt.graphics.Image;
27 import org.eclipse.swt.graphics.ImageData;
28 import org.eclipse.swt.graphics.ImageLoader;
29 import org.eclipse.swt.graphics.RGB;
30 import org.eclipse.swt.graphics.Rectangle;
31 import org.eclipse.swt.layout.GridData;
32 import org.eclipse.swt.layout.GridLayout;
33 import org.eclipse.swt.layout.RowLayout;
34 import org.eclipse.swt.widgets.Button;
35 import org.eclipse.swt.widgets.Canvas;
36 import org.eclipse.swt.widgets.Combo;
37 import org.eclipse.swt.widgets.Composite;
38 import org.eclipse.swt.widgets.Dialog;
39 import org.eclipse.swt.widgets.Display;
40 import org.eclipse.swt.widgets.FileDialog;
41 import org.eclipse.swt.widgets.Label;
42 import org.eclipse.swt.widgets.Menu;
43 import org.eclipse.swt.widgets.MenuItem;
44 import org.eclipse.swt.widgets.MessageBox;
45 import org.eclipse.swt.widgets.Sash;
46 import org.eclipse.swt.widgets.ScrollBar;
47 import org.eclipse.swt.widgets.Shell;
48 import org.eclipse.swt.widgets.Text;
49
50 import com.port80.eclipse.util.UIUtil;
51 import com.port80.util.Msg;
52 import com.port80.util.Sprint;
53 import com.port80.util.SystemWatch;
54
55 /**
56 * An image viewer using swt.
57 *
58 * <li>A GC can be created on an Image and then use it to draw into the Image.</li>
59 * <li>To display very large image, pixel data is loaded into ImageData and then
60 * tiles of the data are used to create Image's for display.</li>
61 *
62 * @author chrisl
63 */
64 public class ImageViewer1 {
65
66 ////////////////////////////////////////////////////////////////////////
67
68 private static final String NAME = "ImageViewer1";
69
70 private static final String[] IMAGE_SUFFICES =
71 new String[] {
72 "*.bmp; *.gif; *.ico; *.jpg; *.pcx; *.png; *.tif",
73 "*.bmp",
74 "*.gif",
75 "*.ico",
76 "*.jpg",
77 "*.pcx",
78 "*.png",
79 "*.tif" };
80
81 private static final String[] IMAGE_FILTER_NAMES =
82 new String[] {
83 i18n("All_images") + " (bmp, gif, ico, jpg, pcx, png, tif)",
84 "BMP (*.bmp)",
85 "GIF (*.gif)",
86 "ICO (*.ico)",
87 "JPEG (*.jpg)",
88 "PCX (*.pcx)",
89 "PNG (*.png)",
90 "TIFF (*.tif)" };
91
92 ////////////////////////////////////////////////////////////////////////
93
94 private Display fDisplay;
95 private Shell fShell;
96 private Font fFont;
97 private Color fWhiteColor, fBlackColor, fLightColor;
98 private Cursor fCrossCursor;
99 private GC fImageCanvasGC;
100 private Image fImage;
101 private ImageData[] fImageDatas;
102 private ImageData fImageData; // the currently-displayed image data
103 private int fImageDataIndex;
104 private double fScale;
105 private int fX = 0, fY = 0; // Top left corner, used to scroll the image and palette
106 private String fLastPath;
107 private boolean fTransparent, fShowMask;
108 private boolean fIncremental;
109 //
110 private long fLoadTime;
111 private String fFilename;
112 //
113 // Widgets
114 private Combo fScaleCombo;
115 private Canvas fImageCanvas;
116 private Sash fSash;
117 private Label fDataLabel, fStatusLabel;
118 private StyledText fDataText;
119 private Label fInfoLabel;
120 //
121 private boolean isResizing;
122
123 ////////////////////////////////////////////////////////////////////////
124
125 public static void main(String[] args) {
126
127 Display display = new Display();
128 ImageViewer1 app = new ImageViewer1();
129 Shell shell = app.open(display);
130
131 while (!shell.isDisposed())
132 if (!display.readAndDispatch())
133 display.sleep();
134 display.dispose();
135 }
136
137 ////////////////////////////////////////////////////////////////////////
138
139 public Shell open(Display display) {
140
141 // Create a window and set its title.
142 this.fDisplay = display;
143 this.fShell = new Shell(fDisplay);
144
145 // Create colors and fonts.
146 fWhiteColor = new Color(display, 255, 255, 255);
147 fBlackColor = new Color(display, 0, 0, 0);
148 fLightColor = new Color(display, 0xd8, 0xd8, 0xd8);
149 fFont = new Font(display, "verdana", 11, 0);
150 fCrossCursor = new Cursor(display, SWT.CURSOR_CROSS);
151
152 fShell.setText(NAME);
153
154 // Hook resize and dispose listeners.
155 fShell.addControlListener(new ControlAdapter() {
156 public void controlResized(ControlEvent event) {
157 resizeShell(event);
158 }
159 });
160 fShell.addShellListener(new ShellAdapter() {
161 public void shellClosed(ShellEvent e) {
162 e.doit = true;
163 }
164 });
165 fShell.addDisposeListener(new DisposeListener() {
166 public void widgetDisposed(DisposeEvent e) {
167 dispose();
168 }
169 });
170
171 // Add a menu bar and widgets.
172 createMenuBar();
173 createWidgets();
174 fShell.pack();
175
176 // Create a GC for drawing, and hook the listener to dispose it.
177 fImageCanvasGC = new GC(fImageCanvas);
178 fImageCanvas.addDisposeListener(new DisposeListener() {
179 public void widgetDisposed(DisposeEvent e) {
180 disposeImageCanvasGC();
181 }
182 });
183
184 // Open the window
185 fShell.open();
186 return fShell;
187 }
188
189 void dispose() {
190 // Clean up.
191 fWhiteColor.dispose();
192 fBlackColor.dispose();
193 fLightColor.dispose();
194 fFont.dispose();
195 fCrossCursor.dispose();
196 }
197
198 void disposeImageCanvasGC() {
199 fImageCanvasGC.dispose();
200 }
201
202 Shell getShell() {
203 return fShell;
204 }
205
206 Display getDisplay() {
207 return fDisplay;
208 }
209
210 Image getImage() {
211 return fImage;
212 }
213
214 void createWidgets() {
215 // Add the widgets to the shell in a grid layout.
216 GridLayout layout = new GridLayout();
217 layout.marginHeight = 0;
218 layout.numColumns = 2;
219 fShell.setLayout(layout);
220
221 // Add a composite to contain some control widgets across the top.
222 Composite controls = new Composite(fShell, SWT.NULL);
223 RowLayout rowLayout = new RowLayout();
224 rowLayout.marginTop = 2;
225 rowLayout.marginBottom = 2;
226 rowLayout.spacing = 8;
227 controls.setLayout(rowLayout);
228 controls.setLayoutData(UIUtil.fillCell(1, 1, false, false));
229
230 // RowLayout is top aligned. To make label text at middle, need to set label height.
231 fInfoLabel = new Label(fShell, SWT.NULL);
232 fInfoLabel.setToolTipText("Image info");
233 fInfoLabel.setText("Image info");
234 fInfoLabel.setLayoutData(UIUtil.fillCell(1, 1, true, false));
235 // Combo to change the x scale.
236 String[] values =
237 {
238 "5 %",
239 "10 %",
240 "25 %",
241 "33 %",
242 "50 %",
243 "75 %",
244 "100 %",
245 "125 %",
246 "133 %",
247 "150 %",
248 "175 %",
249 "200 %",
250 "300 %",
251 "500 %",
252 "750 %",
253 "1000 %",
254 };
255 fScaleCombo = new Combo(controls, SWT.DROP_DOWN);
256 for (int i = 0; i < values.length; i++) {
257 fScaleCombo.add(values[i]);
258 }
259 fScaleCombo.setToolTipText("Scale");
260 fScaleCombo.select(fScaleCombo.indexOf("100 %"));
261 fScaleCombo.addSelectionListener(new SelectionAdapter() {
262 public void widgetSelected(SelectionEvent event) {
263 scaleImage();
264 }
265 });
266
267 // Canvas to show the image.
268 fImageCanvas = new Canvas(fShell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.NO_REDRAW_RESIZE);
269 fImageCanvas.setBackground(fWhiteColor);
270 fImageCanvas.setCursor(fCrossCursor);
271 fImageCanvas.setLayoutData(UIUtil.fillCell(15, 2, 1024, 768, true, true));
272 fImageCanvas.addPaintListener(new PaintListener() {
273 public void paintControl(PaintEvent event) {
274 paintImage(event);
275 }
276 });
277 fImageCanvas.addMouseMoveListener(new MouseMoveListener() {
278 public void mouseMove(MouseEvent event) {
279 showColorAt(event.x, event.y);
280 }
281 });
282
283 // Set up the image canvas scroll bars.
284 ScrollBar horizontal = fImageCanvas.getHorizontalBar();
285 horizontal.setVisible(true);
286 horizontal.setMinimum(0);
287 horizontal.setEnabled(false);
288 horizontal.addSelectionListener(new SelectionAdapter() {
289 public void widgetSelected(SelectionEvent event) {
290 scrollHorizontally((ScrollBar) event.widget);
291 }
292 });
293 ScrollBar vertical = fImageCanvas.getVerticalBar();
294 vertical.setVisible(true);
295 vertical.setMinimum(0);
296 vertical.setEnabled(false);
297 vertical.addSelectionListener(new SelectionAdapter() {
298 public void widgetSelected(SelectionEvent event) {
299 scrollVertically((ScrollBar) event.widget);
300 }
301 });
302
303 // Label to show status and cursor location in image.
304 fStatusLabel = new Label(fShell, SWT.NULL);
305 fStatusLabel.setText("");
306 fStatusLabel.setLayoutData(UIUtil.fillCell(1, 2, true, false));
307 }
308
309 Menu createMenuBar() {
310 // Menu bar.
311 Menu menuBar = new Menu(fShell, SWT.BAR);
312 fShell.setMenuBar(menuBar);
313 createFileMenu(menuBar);
314 return menuBar;
315 }
316
317 void createFileMenu(Menu menuBar) {
318 // File menu
319 MenuItem item = new MenuItem(menuBar, SWT.CASCADE);
320 item.setText("File");
321 Menu fileMenu = new Menu(fShell, SWT.DROP_DOWN);
322 item.setMenu(fileMenu);
323
324 item = new MenuItem(fileMenu, SWT.NULL);
325 item.setText("&Open");
326 item.setAccelerator(SWT.CTRL + 'O');
327 item.addSelectionListener(new SelectionAdapter() {
328 public void widgetSelected(SelectionEvent event) {
329 openFile();
330 }
331 });
332
333 item = new MenuItem(fileMenu, SWT.NULL);
334 item.setText("Open &URL");
335 item.setAccelerator(SWT.CTRL + 'U');
336 item.addSelectionListener(new SelectionAdapter() {
337 public void widgetSelected(SelectionEvent event) {
338 openURL();
339 }
340 });
341
342 new MenuItem(fileMenu, SWT.SEPARATOR);
343
344 // File -> Exit
345 item = new MenuItem(fileMenu, SWT.NULL);
346 item.setText("Exit");
347 item.addSelectionListener(new SelectionAdapter() {
348 public void widgetSelected(SelectionEvent event) {
349 getShell().close();
350 }
351 });
352
353 // Test menu
354 item = new MenuItem(menuBar, SWT.CASCADE);
355
356 }
357
358 ////////////////////////////////////////////////////////////////////////
359
360 public void openFile() {
361 resetScaleCombo();
362
363 // Get the user to choose an image file.
364 FileDialog fileChooser = new FileDialog(fShell, SWT.OPEN);
365 if (fLastPath != null)
366 fileChooser.setFilterPath(fLastPath);
367 fileChooser.setFilterExtensions(IMAGE_SUFFICES);
368 fileChooser.setFilterNames(IMAGE_FILTER_NAMES);
369 String filename = fileChooser.open();
370 fLastPath = fileChooser.getFilterPath();
371 if (filename == null)
372 return;
373
374 Cursor waitCursor = new Cursor(fDisplay, SWT.CURSOR_WAIT);
375 fShell.setCursor(waitCursor);
376 fImageCanvas.setCursor(waitCursor);
377 try {
378 clear();
379 ImageLoader loader = new ImageLoader();
380 // Read the new image(s) from the chosen file.
381 SystemWatch timer = new SystemWatch().start();
382 long startTime = System.currentTimeMillis();
383 fImageDatas = loader.load(filename);
384 fLoadTime = System.currentTimeMillis() - startTime;
385 System.err.println(NAME + ".open(): load time=" + timer.stop().toString());
386 if (fImageDatas.length > 0) {
387 // Cache the filename.
388 fFilename = filename;
389
390 // Display the first image in the file.
391 fImageDataIndex = 0;
392 displayImage(fImageDatas[fImageDataIndex]);
393 resetScrollBars();
394 }
395 } catch (SWTException e) {
396 showErrorDialog(i18n("Loading_lc"), filename, e);
397 } finally {
398 fShell.setCursor(null);
399 fImageCanvas.setCursor(fCrossCursor);
400 waitCursor.dispose();
401 }
402 }
403
404 public void openURL() {
405 resetScaleCombo();
406
407 // Get the user to choose an image URL.
408 TextPrompter textPrompter = new TextPrompter(fShell, SWT.APPLICATION_MODAL | SWT.DIALOG_TRIM);
409 textPrompter.setText(i18n("OpenURLDialog"));
410 textPrompter.setMessage(i18n("EnterURL"));
411 String urlname = textPrompter.open();
412 if (urlname == null)
413 return;
414
415 Cursor waitCursor = new Cursor(fDisplay, SWT.CURSOR_WAIT);
416 fShell.setCursor(waitCursor);
417 fImageCanvas.setCursor(waitCursor);
418 try {
419 clear();
420 URL url = new URL(urlname);
421 InputStream stream = url.openStream();
422 ImageLoader loader = new ImageLoader();
423 // Read the new image(s) from the chosen file.
424 long startTime = System.currentTimeMillis();
425 fImageDatas = loader.load(stream);
426 fLoadTime = System.currentTimeMillis() - startTime;
427 if (fImageDatas.length > 0) {
428 fFilename = null;
429 // Display the first image in the file.
430 fImageDataIndex = 0;
431 displayImage(fImageDatas[fImageDataIndex]);
432 resetScrollBars();
433 }
434 } catch (Exception e) {
435 showErrorDialog(i18n("Loading_lc"), urlname, e);
436 } finally {
437 fShell.setCursor(null);
438 fImageCanvas.setCursor(fCrossCursor);
439 waitCursor.dispose();
440 }
441 }
442
443 void displayImage(ImageData newImageData) {
444 // Dispose of the old image, if there was one.
445 if (fImage != null)
446 fImage.dispose();
447
448 try {
449 // Cache the new image and imageData.
450 fImage = new Image(fDisplay, newImageData);
451 fImageData = newImageData;
452 } catch (SWTException e) {
453 showErrorDialog(i18n("Creating_from") + " ", fFilename, e);
454 fImage = null;
455 return;
456 }
457
458 // Update the widgets with the new image info.
459 String string = createMsg(i18n("Analyzer_on"), fFilename);
460 fShell.setText(string);
461
462 fInfoLabel.setText(
463 fFilename
464 + ": w="
465 + fImageData.width
466 + ", h="
467 + fImageData.height
468 + ", depth="
469 + fImageData.depth
470 + Sprint.f(" (%.2f)", fLoadTime / 1000f));
471 // Redraw both canvases.
472 fImageCanvas.redraw();
473 }
474
475 void paintImage(PaintEvent event) {
476 // Image paintImage = fImage;
477 // int transparentPixel = fImageData.transparentPixel;
478 // if (transparentPixel != -1 && !fTransparent) {
479 // fImageData.transparentPixel = -1;
480 // paintImage = new Image(fDisplay, fImageData);
481 // }
482 // int w = (int) Math.round(fImageData.width * fScale);
483 // int h = (int) Math.round(fImageData.height * fScale);
484 if (false)
485 Msg.err(
486 NAME
487 + ".paintImage(): event="
488 + event.x
489 + ","
490 + event.y
491 + ","
492 + event.width
493 + ","
494 + event.height
495 + ", fX,fY="
496 + fX
497 + ","
498 + fY);
499 if (fImageData == null)
500 return;
501 int w = fImageData.width;
502 int h = fImageData.height;
503 event.gc.drawImage(fImage, 0, 0, w, h, fX + fImageData.x, fY + fImageData.y, w, h);
504 if (fShowMask && (fImageData.getTransparencyType() != SWT.TRANSPARENCY_NONE)) {
505 ImageData maskImageData = fImageData.getTransparencyMask();
506 Image maskImage = new Image(fDisplay, maskImageData);
507 event.gc.drawImage(
508 maskImage,
509 0,
510 0,
511 fImageData.width,
512 fImageData.height,
513 w + 10 + fX + fImageData.x,
514 fY + fImageData.y,
515 w,
516 h);
517 maskImage.dispose();
518 }
519 // if (transparentPixel != -1 && !fTransparent) {
520 // fImageData.transparentPixel = transparentPixel;
521 // paintImage.dispose();
522 // }
523 }
524
525 /*
526 * Called when the mouse moves in the image canvas.
527 * Show the color of the image at the point under the mouse.
528 */
529 void showColorAt(int mx, int my) {
530 if (fImageData == null)
531 return;
532 int x = mx - fImageData.x - fX;
533 int y = my - fImageData.y - fY;
534 showColorForPixel(x, y);
535 }
536
537 /*
538 * Set the status label to show color information
539 * for the specified pixel in the image.
540 */
541 void showColorForPixel(int x, int y) {
542 if (x >= 0 && x < fImageData.width && y >= 0 && y < fImageData.height) {
543 int pixel = fImageData.getPixel(x, y);
544 RGB rgb = fImageData.palette.getRGB(pixel);
545
546 Object[] args =
547 { new Integer(x), new Integer(y), new Integer(pixel), Integer.toHexString(pixel), rgb };
548 if (pixel == fImageData.transparentPixel) {
549 fStatusLabel.setText(createMsg("Color at transparent pixel: ", args));
550 } else {
551 fStatusLabel.setText(Sprint.f("Color at: %d,%d=%06x").a(x).a(y).a(pixel).end());
552 }
553 } else {
554 fStatusLabel.setText("");
555 }
556 }
557
558 /*
559 * Called when a mouse down or key press is detected
560 * in the data text. Show the color of the pixel at
561 * the caret position in the data text.
562 */
563 void showColorForData() {
564 }
565
566 ////////////////////////////////////////////////////////////////////////
567
568 /*
569 * Called when the image canvas' horizontal scrollbar is selected.
570 */
571 void scrollHorizontally(ScrollBar scrollBar) {
572 if (fImage == null)
573 return;
574 Rectangle canvasBounds = fImageCanvas.getClientArea();
575 int width = (int) Math.round(fImageData.width);
576 int height = (int) Math.round(fImageData.height);
577 if (width > canvasBounds.width) {
578 // Only scroll if the image is bigger than the canvas.
579 int x = -scrollBar.getSelection();
580 if (x + width < canvasBounds.width) {
581 // Don't scroll past the end of the image.
582 x = canvasBounds.width - width;
583 }
584 fImageCanvas.scroll(x, fY, fX, fY, width, height, false);
585 fX = x;
586 }
587 }
588
589 /*
590 * Called when the image canvas' vertical scrollbar is selected.
591 */
592 void scrollVertically(ScrollBar scrollBar) {
593 if (fImage == null)
594 return;
595 Rectangle canvasBounds = fImageCanvas.getClientArea();
596 int width = (int) Math.round(fImageData.width);
597 int height = (int) Math.round(fImageData.height);
598 if (height > canvasBounds.height) {
599 // Only scroll if the image is bigger than the canvas.
600 int y = -scrollBar.getSelection();
601 if (y + height < canvasBounds.height) {
602 // Don't scroll past the end of the image.
603 y = canvasBounds.height - height;
604 }
605 fImageCanvas.scroll(fX, y, fX, fY, width, height, false);
606 fY = y;
607 }
608 }
609
610 /*
611 * Called when the ScaleX combo selection changes.
612 */
613 void scaleImage() {
614 try {
615 String text = fScaleCombo.getText();
616 int index = text.indexOf(' ');
617 fScale = Float.parseFloat(text.substring(0, index)) / 100;
618 } catch (NumberFormatException e) {
619 fScale = 1;
620 fScaleCombo.select(fScaleCombo.indexOf("100 %"));
621 }
622 if (fImage == null)
623 return;
624 // Scale image to a new buffer.
625 fImageData = fImageDatas[fImageDataIndex];
626 if (fScale != 1) {
627 fImageData =
628 fImageData.scaledTo(
629 (int) Math.round(fImageData.width * fScale),
630 (int) Math.round(fImageData.height * fScale));
631 }
632 resizeScrollBars();
633 fX = -fImageCanvas.getHorizontalBar().getSelection();
634 fY = -fImageCanvas.getVerticalBar().getSelection();
635 displayImage(fImageData);
636 }
637
638 // Reset the scale combos to 1.
639 void resetScaleCombo() {
640 fScale = 1;
641 fScaleCombo.select(fScaleCombo.indexOf("100 %"));
642 }
643
644 // Reset the scroll bars to 0.
645 void resetScrollBars() {
646 if (fImage == null)
647 return;
648 fX = 0;
649 fY = 0;
650 resizeScrollBars();
651 fImageCanvas.getHorizontalBar().setSelection(0);
652 fImageCanvas.getVerticalBar().setSelection(0);
653 }
654
655 void resizeScrollBars() {
656 // Set the max and thumb for the image canvas scroll bars.
657 ScrollBar horizontal = fImageCanvas.getHorizontalBar();
658 ScrollBar vertical = fImageCanvas.getVerticalBar();
659 Rectangle canvasBounds = fImageCanvas.getClientArea();
660 int width = (int) Math.round(fImageData.width);
661 if (width > canvasBounds.width) {
662 // The image is wider than the canvas.
663 // Set selection such as to keep top left corner of the image stationary.
664 int x = horizontal.getSelection() * width / horizontal.getMaximum();
665 horizontal.setEnabled(true);
666 horizontal.setMaximum(width);
667 horizontal.setSelection(x);
668 horizontal.setThumb(canvasBounds.width);
669 horizontal.setPageIncrement(canvasBounds.width);
670 } else {
671 // The canvas is wider than the image.
672 horizontal.setEnabled(false);
673 if (fX != 0) {
674 // Make sure the image is completely visible.
675 fX = 0;
676 fImageCanvas.redraw();
677 }
678 }
679 int height = (int) Math.round(fImageData.height);
680 if (height > canvasBounds.height) {
681 // The image is taller than the canvas.
682 // Set selection such as to keep top left corner of the image stationary.
683 vertical.setEnabled(true);
684 vertical.setMaximum(height);
685 vertical.setThumb(canvasBounds.height);
686 vertical.setPageIncrement(canvasBounds.height);
687 } else {
688 // The canvas is taller than the image.
689 vertical.setEnabled(false);
690 if (fY != 0) {
691 // Make sure the image is completely visible.
692 fY = 0;
693 fImageCanvas.redraw();
694 }
695 }
696 }
697
698 void resizeShell(ControlEvent event) {
699 if (isResizing)
700 return;
701 if (fImage == null || fShell.isDisposed())
702 return;
703 isResizing = true;
704 resizeScrollBars();
705 isResizing = false;
706 }
707
708 void clear() {
709 fImageDatas = null;
710 fImageData = null;
711 if (fImage != null)
712 fImage.dispose();
713 fImage = null;
714 }
715
716 ////////////////////////////////////////////////////////////////////////
717
718 /*
719 * Open an error dialog displaying the specified information.
720 */
721 void showErrorDialog(String operation, String filename, Exception e) {
722 MessageBox box = new MessageBox(fShell, SWT.ICON_ERROR);
723 String message = createMsg(i18n("Error"), new String[] { operation, filename });
724 String errorMessage = "";
725 if (e != null) {
726 if (e instanceof SWTException) {
727 SWTException swte = (SWTException) e;
728 errorMessage = swte.getMessage();
729 if (swte.throwable != null) {
730 errorMessage += ":\n" + swte.throwable.toString();
731 }
732 } else {
733 errorMessage = e.toString();
734 }
735 }
736 box.setMessage(message + errorMessage);
737 box.open();
738 }
739
740 /*
741 * Return a String describing the specified image file type.
742 */
743 static String fileTypeString(int filetype) {
744 if (filetype == SWT.IMAGE_BMP)
745 return "BMP";
746 if (filetype == SWT.IMAGE_GIF)
747 return "GIF";
748 if (filetype == SWT.IMAGE_ICO)
749 return "ICO";
750 if (filetype == SWT.IMAGE_JPEG)
751 return "JPEG";
752 if (filetype == SWT.IMAGE_PNG)
753 return "PNG";
754 return i18n("Unknown_ac") + ": " + filetype;
755 }
756
757 static String createMsg(String msg, Object arg) {
758 MessageFormat formatter = new MessageFormat(msg);
759 return formatter.format(new Object[] { arg });
760 }
761
762 static String i18n(String str) {
763 return str;
764 }
765
766 ////////////////////////////////////////////////////////////////////////
767
768 class TextPrompter extends Dialog {
769 String message = "";
770 String result = null;
771 Shell dialog;
772 Text text;
773 public TextPrompter(Shell parent, int style) {
774 super(parent, style);
775 }
776 public TextPrompter(Shell parent) {
777 this(parent, SWT.APPLICATION_MODAL);
778 }
779 public String getMessage() {
780 return message;
781 }
782 public void setMessage(String string) {
783 message = string;
784 }
785 public String open() {
786 dialog = new Shell(getParent(), getStyle());
787 dialog.setText(getText());
788 dialog.setLayout(new GridLayout());
789 Label label = new Label(dialog, SWT.NULL);
790 label.setText(message);
791 label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
792 text = new Text(dialog, SWT.SINGLE | SWT.BORDER);
793 GridData data = new GridData(GridData.FILL_HORIZONTAL);
794 data.widthHint = 300;
795 text.setLayoutData(data);
796 Composite buttons = new Composite(dialog, SWT.NONE);
797 GridLayout grid = new GridLayout();
798 grid.numColumns = 2;
799 buttons.setLayout(grid);
800 buttons.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
801 Button ok = new Button(buttons, SWT.PUSH);
802 ok.setText(i18n("OK"));
803 data = new GridData();
804 data.widthHint = 75;
805 ok.setLayoutData(data);
806 ok.addSelectionListener(new SelectionAdapter() {
807 public void widgetSelected(SelectionEvent e) {
808 result = text.getText();
809 dialog.dispose();
810 }
811 });
812 Button cancel = new Button(buttons, SWT.PUSH);
813 cancel.setText(i18n("Cancel"));
814 data = new GridData();
815 data.widthHint = 75;
816 cancel.setLayoutData(data);
817 cancel.addSelectionListener(new SelectionAdapter() {
818 public void widgetSelected(SelectionEvent e) {
819 dialog.dispose();
820 }
821 });
822 dialog.setDefaultButton(ok);
823 dialog.pack();
824 dialog.open();
825 while (!dialog.isDisposed()) {
826 if (!getDisplay().readAndDispatch())
827 getDisplay().sleep();
828 }
829 return result;
830 }
831 }
832
833 ////////////////////////////////////////////////////////////////////////
834
835 }