1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.vectomatic.svg.edit.client;
19
20 import java.util.ArrayList;
21 import java.util.HashMap;
22 import java.util.List;
23 import java.util.Map;
24
25 import org.vectomatic.dom.svg.OMSVGDocument;
26 import org.vectomatic.dom.svg.OMSVGSVGElement;
27 import org.vectomatic.dom.svg.impl.SVGElement;
28 import org.vectomatic.dom.svg.impl.SVGSVGElement;
29 import org.vectomatic.dom.svg.ui.SVGResource;
30 import org.vectomatic.dom.svg.utils.OMSVGParser;
31 import org.vectomatic.dom.svg.utils.SVGConstants;
32 import org.vectomatic.file.File;
33 import org.vectomatic.file.FileList;
34 import org.vectomatic.file.FileUploadExt;
35 import org.vectomatic.svg.edit.client.command.CommandFactories;
36 import org.vectomatic.svg.edit.client.command.CommandFactorySelector;
37 import org.vectomatic.svg.edit.client.engine.SVGModel;
38 import org.vectomatic.svg.edit.client.engine.SVGProcessor;
39 import org.vectomatic.svg.edit.client.event.ActivateWindowEvent;
40 import org.vectomatic.svg.edit.client.event.ActivateWindowHandler;
41 import org.vectomatic.svg.edit.client.event.DeactivateWindowEvent;
42 import org.vectomatic.svg.edit.client.event.DeactivateWindowHandler;
43 import org.vectomatic.svg.edit.client.event.HasActivateWindowHandlers;
44 import org.vectomatic.svg.edit.client.event.HasDeactivateWindowHandlers;
45 import org.vectomatic.svg.edit.client.gxt.panels.CommandFactoryToolBar;
46 import org.vectomatic.svg.edit.client.gxt.widget.RecentDocMenuItem;
47 import org.vectomatic.svg.edit.client.gxt.widget.ViewportExt;
48 import org.vectomatic.svg.edit.client.inspector.InspectorWindow;
49 import org.vectomatic.svg.edit.client.load.FileLoadRequest;
50 import org.vectomatic.svg.edit.client.load.ILoadRequest;
51 import org.vectomatic.svg.edit.client.load.InternalLoadRequest;
52 import org.vectomatic.svg.edit.client.load.NewDocRequest;
53 import org.vectomatic.svg.edit.client.load.RSSReader;
54 import org.vectomatic.svg.edit.client.load.UrlLoadRequest;
55 import org.vectomatic.svg.edit.client.model.MetaModel;
56 import org.vectomatic.svg.edit.client.model.svg.CssContextModel;
57 import org.vectomatic.svg.edit.client.model.svg.SVGCircleElementModel;
58 import org.vectomatic.svg.edit.client.model.svg.SVGEllipseElementModel;
59 import org.vectomatic.svg.edit.client.model.svg.SVGImageElementModel;
60 import org.vectomatic.svg.edit.client.model.svg.SVGLineElementModel;
61 import org.vectomatic.svg.edit.client.model.svg.SVGNamedElementModel;
62 import org.vectomatic.svg.edit.client.model.svg.SVGPolygonElementModel;
63 import org.vectomatic.svg.edit.client.model.svg.SVGPolylineElementModel;
64 import org.vectomatic.svg.edit.client.model.svg.SVGRectElementModel;
65 import org.vectomatic.svg.edit.client.utils.DecoratedImageCache;
66 import org.vectomatic.svg.edit.client.utils.ImageLoader;
67
68 import com.extjs.gxt.ui.client.Style.LayoutRegion;
69 import com.extjs.gxt.ui.client.event.Events;
70 import com.extjs.gxt.ui.client.event.Listener;
71 import com.extjs.gxt.ui.client.event.MenuEvent;
72 import com.extjs.gxt.ui.client.event.MessageBoxEvent;
73 import com.extjs.gxt.ui.client.event.SelectionListener;
74 import com.extjs.gxt.ui.client.event.WindowEvent;
75 import com.extjs.gxt.ui.client.util.Rectangle;
76 import com.extjs.gxt.ui.client.util.Size;
77 import com.extjs.gxt.ui.client.widget.Component;
78 import com.extjs.gxt.ui.client.widget.ContentPanel;
79 import com.extjs.gxt.ui.client.widget.Info;
80 import com.extjs.gxt.ui.client.widget.LayoutContainer;
81 import com.extjs.gxt.ui.client.widget.MessageBox;
82 import com.extjs.gxt.ui.client.widget.Window;
83 import com.extjs.gxt.ui.client.widget.button.Button;
84 import com.extjs.gxt.ui.client.widget.layout.BorderLayout;
85 import com.extjs.gxt.ui.client.widget.layout.BorderLayoutData;
86 import com.extjs.gxt.ui.client.widget.layout.HBoxLayout;
87 import com.extjs.gxt.ui.client.widget.layout.HBoxLayout.HBoxLayoutAlign;
88 import com.extjs.gxt.ui.client.widget.layout.HBoxLayoutData;
89 import com.extjs.gxt.ui.client.widget.menu.Menu;
90 import com.extjs.gxt.ui.client.widget.menu.MenuBar;
91 import com.extjs.gxt.ui.client.widget.menu.MenuBarItem;
92 import com.extjs.gxt.ui.client.widget.menu.MenuItem;
93 import com.extjs.gxt.ui.client.widget.menu.SeparatorMenuItem;
94 import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
95 import com.google.gwt.core.client.EntryPoint;
96 import com.google.gwt.core.client.GWT;
97 import com.google.gwt.dom.client.Style;
98 import com.google.gwt.dom.client.Style.Unit;
99 import com.google.gwt.dom.client.Style.Visibility;
100 import com.google.gwt.event.dom.client.ChangeEvent;
101 import com.google.gwt.event.dom.client.ChangeHandler;
102 import com.google.gwt.event.logical.shared.InitializeEvent;
103 import com.google.gwt.event.logical.shared.InitializeHandler;
104 import com.google.gwt.event.shared.EventBus;
105 import com.google.gwt.event.shared.GwtEvent;
106 import com.google.gwt.event.shared.HandlerRegistration;
107 import com.google.gwt.event.shared.SimpleEventBus;
108 import com.google.gwt.resources.client.ImageResource;
109 import com.google.gwt.user.client.DOM;
110 import com.google.gwt.user.client.Window.Location;
111 import com.google.gwt.user.client.ui.AbstractImagePrototype;
112 import com.google.gwt.user.client.ui.DialogBox;
113 import com.google.gwt.user.client.ui.RootPanel;
114
115
116
117
118
119 public class SvgrealApp implements EntryPoint, HasActivateWindowHandlers, HasDeactivateWindowHandlers {
120
121
122
123 private static final String PARAM_LOCALE = "locale";
124
125
126
127 private static final String PARAM_CODE_SERVER = "gwt.codesvr";
128
129
130
131 private static final String PARAM_DEMO = "demo";
132
133
134
135 private static SvgrealApp instance;
136
137
138
139 private EventBus eventBus;
140
141
142
143 private List<SVGWindow> svgWindows;
144
145
146
147 private SVGWindow activeWindow;
148
149
150
151 private MessageBox openUrlBox;
152
153
154
155 private RSSReader rssReader;
156
157
158
159 private AboutDialog aboutDialog;
160
161
162
163 private InspectorWindow inspectorWindow;
164
165
166
167 private CommandFactorySelector commandFactorySelector;
168
169
170
171 private CommandFactoryToolBar commandToolBar;
172
173
174
175 FileUploadExt fileUpload;
176
177
178
179
180 private CssContextModel cssContext;
181
182
183
184 private DecoratedImageCache imageCache;
185
186 private List<MetaModel<?>> metaModels;
187
188
189
190
191 private int windowSlot;
192 private ViewportExt viewport;
193 private Menu recentDocsMenu;
194 private MenuItem resetViewItem;
195 private MenuItem tileWindowsItem;
196 private MenuItem stackWindowsItem;
197 private MenuItem closeWindowItem;
198 private MenuItem exportAsSvgMenuItem;
199 private Menu displayWindowMenu;
200 private MenuItem displayWindowMenuItem;
201 private Map<String, ImageResource> localeToIcon;
202
203
204
205 private SelectionListener<MenuEvent> dispatcher;
206 private Menu languageMenu;
207
208 public SvgrealApp() {
209
210 }
211
212 public void onModuleLoad() {
213 instance = this;
214 GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler() {
215 public void onUncaughtException(Throwable throwable) {
216 GWT.log("Uncaught exception", throwable);
217 if (!GWT.isScript()) {
218 String text = "Uncaught exception: ";
219 while (throwable != null) {
220 StackTraceElement[] stackTraceElements = throwable
221 .getStackTrace();
222 text += throwable.toString() + "\n";
223 for (int i = 0; i < stackTraceElements.length; i++) {
224 text += " at " + stackTraceElements[i] + "\n";
225 }
226 throwable = throwable.getCause();
227 if (throwable != null) {
228 text += "Caused by: ";
229 }
230 }
231 DialogBox dialogBox = new DialogBox(true);
232 DOM.setStyleAttribute(dialogBox.getElement(),
233 "backgroundColor", "#ABCDEF");
234 System.err.print(text);
235 text = text.replaceAll(" ", " ");
236 dialogBox.setHTML("<pre>" + text + "</pre>");
237 dialogBox.center();
238 }
239 }
240 });
241 AppBundle.INSTANCE.css().ensureInjected();
242
243
244 OMSVGDocument doc = OMSVGParser.currentDocument();
245 SVGElement element = doc.createSVGPathElement().getElement().cast();
246 element.getStyle().setProperty(SVGConstants.CSS_FILL_PROPERTY, SVGConstants.CSS_LIGHTBLUE_VALUE);
247 element.getStyle().setProperty(SVGConstants.CSS_STROKE_PROPERTY, SVGConstants.CSS_BLACK_VALUE);
248 SVGNamedElementModel.createTitleDesc(element, AppConstants.INSTANCE.graphicalContext());
249 cssContext = new CssContextModel(element);
250
251 svgWindows = new ArrayList<SVGWindow>();
252 viewport = new ViewportExt();
253
254 viewport.setLayout(new BorderLayout());
255 HBoxLayout hboxLayout = new HBoxLayout();
256 hboxLayout.setHBoxLayoutAlign(HBoxLayoutAlign.TOP);
257 LayoutContainer menuBarContainer = new LayoutContainer(hboxLayout);
258 HBoxLayoutData layoutData = new HBoxLayoutData();
259 layoutData.setFlex(1);
260 menuBarContainer.add(createMenuBar(), layoutData);
261 menuBarContainer.add(createLanguageBar(), new HBoxLayoutData());
262 viewport.add(menuBarContainer, new BorderLayoutData(LayoutRegion.NORTH, getWindowBarHeight()));
263 viewport.setStyleAttribute("background-color", SVGConstants.CSS_BEIGE_VALUE);
264
265 commandToolBar = new CommandFactoryToolBar(CommandFactories.getAllFactoriesStore(), getCommandFactorySelector());
266 ContentPanel commandPanel = new ContentPanel();
267 commandPanel.setHeaderVisible(false);
268 commandPanel.setBottomComponent(commandToolBar);
269 viewport.add(commandPanel, new BorderLayoutData(LayoutRegion.SOUTH, getWindowBarHeight()));
270
271
272 update();
273
274 fileUpload = new FileUploadExt();
275 Style style = fileUpload.getElement().getStyle();
276 style.setVisibility(Visibility.HIDDEN);
277 style.setWidth(0, Unit.PX);
278 style.setHeight(0, Unit.PX);
279 fileUpload.addChangeHandler(new ChangeHandler() {
280
281 @Override
282 public void onChange(ChangeEvent event) {
283 processFiles(fileUpload.getFiles());
284 }
285 });
286
287 RootPanel.get().add(viewport);
288 RootPanel.get().add(fileUpload);
289
290
291 ImageLoader loader = new ImageLoader();
292 loader.addInitializeHandler(new InitializeHandler() {
293
294 @Override
295 public void onInitialize(InitializeEvent event) {
296 ImageLoader loader = (ImageLoader) event.getSource();
297 imageCache = new DecoratedImageCache(loader.getImages());
298 init();
299 }
300 });
301 loader.loadImages(new ImageResource[]{
302 AppBundle.INSTANCE.altGlyphDef(),
303 AppBundle.INSTANCE.altGlyphItem(),
304 AppBundle.INSTANCE.altGlyph(),
305 AppBundle.INSTANCE.animateColor(),
306 AppBundle.INSTANCE.animateMotion(),
307 AppBundle.INSTANCE.animate(),
308 AppBundle.INSTANCE.animateTransform(),
309 AppBundle.INSTANCE.circle(),
310 AppBundle.INSTANCE.clipPath(),
311 AppBundle.INSTANCE.colorProfile(),
312 AppBundle.INSTANCE.cursor(),
313 AppBundle.INSTANCE.defs(),
314 AppBundle.INSTANCE.desc(),
315 AppBundle.INSTANCE.ellipse(),
316 AppBundle.INSTANCE.feBlend(),
317 AppBundle.INSTANCE.feColorMatrix(),
318 AppBundle.INSTANCE.feComponentTransfer(),
319 AppBundle.INSTANCE.feComposite(),
320 AppBundle.INSTANCE.feConvolveMatrix(),
321 AppBundle.INSTANCE.feDiffuseLighting(),
322 AppBundle.INSTANCE.feDisplacementMap(),
323 AppBundle.INSTANCE.feDistantLight(),
324 AppBundle.INSTANCE.feFlood(),
325 AppBundle.INSTANCE.feFuncA(),
326 AppBundle.INSTANCE.feFuncB(),
327 AppBundle.INSTANCE.feFuncG(),
328 AppBundle.INSTANCE.feFuncR(),
329 AppBundle.INSTANCE.feGaussianBlur(),
330 AppBundle.INSTANCE.feMergeNode(),
331 AppBundle.INSTANCE.feMerge(),
332 AppBundle.INSTANCE.feMorphology(),
333 AppBundle.INSTANCE.feOffset(),
334 AppBundle.INSTANCE.fePointLight(),
335 AppBundle.INSTANCE.feSpecularLight(),
336 AppBundle.INSTANCE.feSpotLight(),
337 AppBundle.INSTANCE.feTile(),
338 AppBundle.INSTANCE.feTurbulence(),
339 AppBundle.INSTANCE.filter(),
340 AppBundle.INSTANCE.fontFaceFormat(),
341 AppBundle.INSTANCE.fontFaceName(),
342 AppBundle.INSTANCE.fontFace(),
343 AppBundle.INSTANCE.fontFaceSrc(),
344 AppBundle.INSTANCE.fontFaceUri(),
345 AppBundle.INSTANCE.font(),
346 AppBundle.INSTANCE.foreignObject(),
347 AppBundle.INSTANCE.glyph(),
348 AppBundle.INSTANCE.glyphRef(),
349 AppBundle.INSTANCE.g(),
350 AppBundle.INSTANCE.hkern(),
351 AppBundle.INSTANCE.image(),
352 AppBundle.INSTANCE.linearGradient(),
353 AppBundle.INSTANCE.line(),
354 AppBundle.INSTANCE.marker(),
355 AppBundle.INSTANCE.mask(),
356 AppBundle.INSTANCE.metadata(),
357 AppBundle.INSTANCE.missingGlyph(),
358 AppBundle.INSTANCE.mpath(),
359 AppBundle.INSTANCE.path(),
360 AppBundle.INSTANCE.pattern(),
361 AppBundle.INSTANCE.polygon(),
362 AppBundle.INSTANCE.polyline(),
363 AppBundle.INSTANCE.radialGradient(),
364 AppBundle.INSTANCE.rect(),
365 AppBundle.INSTANCE.script(),
366 AppBundle.INSTANCE.set(),
367 AppBundle.INSTANCE.stop(),
368 AppBundle.INSTANCE.style(),
369 AppBundle.INSTANCE.svg(),
370 AppBundle.INSTANCE.switch_(),
371 AppBundle.INSTANCE.symbol(),
372 AppBundle.INSTANCE.textPath(),
373 AppBundle.INSTANCE.text(),
374 AppBundle.INSTANCE.title(),
375 AppBundle.INSTANCE.tref(),
376 AppBundle.INSTANCE.tspan(),
377 AppBundle.INSTANCE.use(),
378 AppBundle.INSTANCE.view(),
379 AppBundle.INSTANCE.vkern(),
380 AppBundle.INSTANCE.error(),
381 AppBundle.INSTANCE.warning(),
382 });
383 }
384
385 private void init() {
386
387 String demo = getParameter(PARAM_DEMO);
388 if (demo != null) {
389 SVGResource[] demoResources = {
390 AppBundle.INSTANCE.fish(),
391 AppBundle.INSTANCE.fries(),
392 AppBundle.INSTANCE.chess(),
393 AppBundle.INSTANCE.sample()
394 };
395 String[] demoNames = {
396 "fish.svg",
397 "fries.svg",
398 "chess.svg",
399 "sample.svg"
400 };
401 for (int i = 0; i < demoResources.length; i++) {
402 if (demo.indexOf(Integer.toString(i)) != -1) {
403 new InternalLoadRequest(demoResources[i], demoNames[i]).load();
404 }
405 }
406 }
407 }
408
409 private MenuBar createMenuBar() {
410 Menu fileMenu = new Menu();
411 AppConstants cst = AppConstants.INSTANCE;
412 final MenuItem newDocumentMenuItem = new MenuItem(cst.newDocumentMenuItem());
413 fileMenu.add(newDocumentMenuItem);
414
415
416 final MenuItem openLocalMenuItem = new MenuItem(cst.openLocalMenuItem());
417 fileMenu.add(openLocalMenuItem);
418 final MenuItem openRssFeedItem = new MenuItem(cst.openRssFeedMenuItem());
419 fileMenu.add(openRssFeedItem);
420 exportAsSvgMenuItem = new MenuItem(cst.exportAsSvgMenuItem());
421 fileMenu.add(exportAsSvgMenuItem);
422 MenuItem recentDocumentsItem = new MenuItem(cst.recentDocumentsMenuItem());
423 recentDocsMenu = new Menu();
424 recentDocumentsItem.setSubMenu(recentDocsMenu);
425 fileMenu.add(recentDocumentsItem);
426
427 Menu windowMenu = new Menu();
428 resetViewItem = new MenuItem(cst.resetViewMenuItem());
429 windowMenu.add(resetViewItem);
430 windowMenu.add(new SeparatorMenuItem());
431 tileWindowsItem = new MenuItem(cst.tileWindowsMenuItem());
432 windowMenu.add(tileWindowsItem);
433 stackWindowsItem = new MenuItem(cst.stackWindowsMenuItem());
434 windowMenu.add(stackWindowsItem);
435 displayWindowMenuItem = new MenuItem(cst.displayWindowMenuItem());
436 displayWindowMenu = new Menu();
437 displayWindowMenuItem.setSubMenu(displayWindowMenu);
438 windowMenu.add(displayWindowMenuItem);
439 windowMenu.add(new SeparatorMenuItem());
440 closeWindowItem = new MenuItem(cst.closeWindowMenuItem());
441 windowMenu.add(closeWindowItem);
442
443 Menu toolsMenu = new Menu();
444 final MenuItem inspectorMenuItem = new MenuItem(cst.inspectorMenuItem());
445 toolsMenu.add(inspectorMenuItem);
446
447 Menu aboutMenu = new Menu();
448 final MenuItem aboutItem = new MenuItem(cst.aboutMenuItem());
449 aboutMenu.add(aboutItem);
450
451 MenuBar menuBar = new MenuBar();
452 menuBar.setBorders(true);
453 menuBar.setStyleAttribute("borderTop", "none");
454 menuBar.add(new MenuBarItem(cst.fileMenu(), fileMenu));
455 menuBar.add(new MenuBarItem(cst.windowMenu(), windowMenu));
456 menuBar.add(new MenuBarItem(cst.toolsMenu(), toolsMenu));
457 menuBar.add(new MenuBarItem(cst.aboutMenu(), aboutMenu));
458
459 dispatcher = new SelectionListener<MenuEvent>() {
460 @Override
461 public void componentSelected(MenuEvent me) {
462 MenuItem item = (MenuItem) me.getItem();
463 if (item == newDocumentMenuItem) {
464 newDocument();
465
466
467 } else if (item == openLocalMenuItem) {
468 openLocal();
469 } else if (item == openRssFeedItem) {
470 openRssFeed();
471 } else if (item == exportAsSvgMenuItem) {
472 exportAsSvg();
473 } else if (item == resetViewItem) {
474 resetView();
475 } else if (item == tileWindowsItem) {
476 tileWindows();
477 } else if (item == stackWindowsItem) {
478 stackWindows();
479 } else if (item == closeWindowItem) {
480 closeWindow(activeWindow);
481 } else if (item == inspectorMenuItem) {
482 inspector();
483 } else if (item == aboutItem) {
484 about();
485 } else if (item.getParentMenu() == displayWindowMenu) {
486 for (SVGWindow window : svgWindows) {
487 if (window.getHeading().equals(item.getText())) {
488 window.setActive(true);
489 window.toFront();
490 break;
491 }
492 }
493 } else if (item.getParentMenu() == languageMenu) {
494 redirect(item.getText());
495 }
496 }
497 };
498 newDocumentMenuItem.addSelectionListener(dispatcher);
499
500 openLocalMenuItem.addSelectionListener(dispatcher);
501 openRssFeedItem.addSelectionListener(dispatcher);
502 exportAsSvgMenuItem.addSelectionListener(dispatcher);
503 resetViewItem.addSelectionListener(dispatcher);
504 tileWindowsItem.addSelectionListener(dispatcher);
505 stackWindowsItem.addSelectionListener(dispatcher);
506 closeWindowItem.addSelectionListener(dispatcher);
507 inspectorMenuItem.addSelectionListener(dispatcher);
508 aboutItem.addSelectionListener(dispatcher);
509 return menuBar;
510 }
511
512 public void redirect(String language) {
513 StringBuilder path = new StringBuilder(GWT.getHostPageBaseURL());
514 path.append("svgreal.html");
515 path.append("?");
516 path.append(PARAM_LOCALE);
517 path.append("=");
518 path.append(language);
519 path.append(copyParam(PARAM_CODE_SERVER));
520 path.append(copyParam(PARAM_DEMO));
521 Location.replace(path.toString());
522 }
523
524 private static String copyParam(String name) {
525 StringBuilder copy = new StringBuilder();
526 String value = getParameter(name);
527 if (value != null && value.length() > 0) {
528 copy.append("&");
529 copy.append(name);
530 copy.append("=");
531 copy.append(value);
532 }
533 return copy.toString();
534 }
535
536 private ToolBar createLanguageBar() {
537 if (localeToIcon == null) {
538 localeToIcon = new HashMap<String, ImageResource>();
539 localeToIcon.put("fr", AppBundle.INSTANCE.flagFr());
540 localeToIcon.put("en", AppBundle.INSTANCE.flagUs());
541 }
542 ToolBar toolBar = new ToolBar();
543 languageMenu = new Menu();
544 for (Map.Entry<String, ImageResource> entry : localeToIcon.entrySet()) {
545 MenuItem item = new MenuItem(entry.getKey(), AbstractImagePrototype.create(entry.getValue()));
546 item.addSelectionListener(dispatcher);
547 languageMenu.add(item);
548 }
549 String locale = getParameter(PARAM_LOCALE);
550 if (!localeToIcon.containsKey(locale)) {
551 locale = "en";
552 }
553 Button languageButton = new Button(locale, AbstractImagePrototype.create((localeToIcon.get(locale))));
554 languageButton.setMenu(languageMenu);
555 toolBar.add(languageButton);
556 toolBar.setWidth(60);
557 toolBar.setHeight(getWindowBarHeight() -1);
558 return toolBar;
559 }
560
561
562 public SVGWindow addWindow(OMSVGSVGElement svg, ILoadRequest request) {
563 String title = request.getTitle();
564 SVGModel model = SVGModel.newInstance(svg, title, SVGProcessor.newIdPrefix());
565 SVGWindow window = new SVGWindow(model);
566 window.setHeading(title);
567 svgWindows.add(window);
568 MenuItem displayItem = new MenuItem(title);
569 displayItem.addSelectionListener(dispatcher);
570 displayWindowMenu.add(displayItem);
571
572
573
574 window.addListener(Events.Activate, new Listener<WindowEvent>() {
575
576 @Override
577 public void handleEvent(WindowEvent we) {
578 SVGWindow svgWindow = (SVGWindow) we.getWindow();
579 GWT.log("VectomaticApp2.Activate(" + svgWindow.getHeading() + ")");
580 if (activeWindow != svgWindow) {
581 if (activeWindow != null) {
582 activeWindow.deactivate();
583 fireEvent(new DeactivateWindowEvent(activeWindow));
584 }
585 activeWindow = svgWindow;
586 activeWindow.activate();
587 fireEvent(new ActivateWindowEvent(activeWindow));
588 }
589 }
590 });
591 window.addListener(Events.BeforeHide, new Listener<WindowEvent>() {
592
593 @Override
594 public void handleEvent(WindowEvent we) {
595 SVGWindow svgWindow = (SVGWindow) we.getWindow();
596 svgWindow.getSvgModel().getSelectionModel().deselectAll();
597 GWT.log("VectomaticApp2.BeforeHide(" + svgWindow.getHeading() + ")");
598 svgWindow.removeAllListeners();
599 svgWindow.deactivate();
600 fireEvent(new DeactivateWindowEvent(svgWindow));
601 for (Component c : displayWindowMenu.getItems()) {
602 MenuItem item = (MenuItem)c;
603 if (item.getText().equals(svgWindow.getHeading())) {
604 displayWindowMenu.remove(item);
605 break;
606 }
607 }
608 svgWindows.remove(svgWindow);
609 activeWindow = null;
610 update();
611 }
612 });
613
614
615 if (!(request instanceof NewDocRequest)) {
616 List<Component> recentDocs = recentDocsMenu.getItems();
617 boolean alreadyInRecentDocs = false;
618 for (Component item : recentDocs) {
619 RecentDocMenuItem menuItem = (RecentDocMenuItem)item;
620 if (request.equals(menuItem.getRequest())) {
621 alreadyInRecentDocs = true;
622 break;
623 }
624 }
625 if (!alreadyInRecentDocs) {
626 if (recentDocs.size() >= 8) {
627 Component oldestItem = recentDocs.get(0);
628 oldestItem.removeAllListeners();
629 recentDocsMenu.remove(oldestItem);
630 }
631 RecentDocMenuItem recentDocItem = new RecentDocMenuItem(request);
632 recentDocsMenu.add(recentDocItem);
633 }
634 }
635
636 slotWindow(window);
637
638 viewport.add(window);
639 window.setVisible(true);
640 update();
641 return window;
642 }
643
644 public void newDocument() {
645 GWT.log("newDocument()");
646 new NewDocRequest().load();
647 }
648
649 public void openUrl() {
650 GWT.log("openUrl()");
651 openUrlBox = MessageBox.prompt(AppConstants.INSTANCE.openUrlMenuItem(), AppConstants.INSTANCE.openUrlText());
652 openUrlBox.addCallback(new Listener<MessageBoxEvent>() {
653 public void handleEvent(MessageBoxEvent be) {
654 new UrlLoadRequest(be.getValue()).load();
655 }
656 });
657 }
658
659 public void info(String command, String message) {
660 Info.display(command, message);
661 }
662
663 public void openRssFeed() {
664 GWT.log("openRssFeed()");
665 if (rssReader == null) {
666 rssReader = new RSSReader();
667 }
668 rssReader.load();
669 rssReader.show();
670 }
671
672 private void openLocal() {
673 GWT.log("openLocal()");
674 fileUpload.click();
675 }
676
677 private void processFiles(FileList files) {
678 for (File file : files) {
679 String type = file.getType();
680 if ("image/svg+xml".equals(type)) {
681 new FileLoadRequest(file).load();
682 }
683 }
684 }
685
686 protected void exportAsSvg() {
687 GWT.log("exportAsSvg()");
688 SVGModel model = getActiveModel();
689 String markup = model.getMarkup();
690 String url = "data:image/svg+xml;base64," + base64encode(markup);
691 String title = ((SVGNamedElementModel)model.getRoot()).getName();
692 com.google.gwt.user.client.Window.open(url, title, "");
693 }
694
695 private static native String base64encode(String str)
696
697 ;
698
699
700 public void resetView() {
701 GWT.log("resetView()");
702 activeWindow.setRotationCompass(0);
703 activeWindow.setScaleSlider(50);
704 }
705 private List<Window> getAllWindows() {
706 List<Window> windows = new ArrayList<Window>(svgWindows);
707 if (inspectorWindow != null && inspectorWindow.isVisible()) {
708 windows.add(inspectorWindow);
709 }
710 return windows;
711 }
712 public void tileWindows() {
713 GWT.log("tileWindows()");
714 List<Window> windows = getAllWindows();
715 Rectangle rect = getRectangle();
716 int count = windows.size();
717 int cols = (int)Math.ceil(Math.sqrt(count));
718 int rows = (int)Math.ceil((double)count/cols);
719 GWT.log("cols=" + cols + "; rows=" + rows);
720 Size windowSize = new Size(rect.width / cols, rect.height / rows);
721 int index = 0;
722 for (Window window : windows) {
723 window.setSize(windowSize.width, windowSize.height);
724 int x = index % cols;
725 int y = index / cols;
726 window.setPagePosition(rect.x + x * windowSize.width, rect.y + y * windowSize.height);
727 index++;
728 }
729 }
730 public void stackWindows() {
731 GWT.log("stackWindows()");
732 windowSlot = 0;
733 for (Window window : getAllWindows()) {
734 slotWindow(window);
735 }
736 }
737
738
739
740
741
742 public void slotWindow(Window window) {
743 Rectangle rect = getRectangle();
744 Size windowSize = new Size((int)(rect.width * 0.8f), (int)(rect.height * 0.8f));
745 int windowBarHeight = getWindowBarHeight();
746 window.setSize(windowSize.width, windowSize.height);
747 int x = rect.x + windowSlot * windowBarHeight;
748 int y = rect.y + windowSlot * windowBarHeight;
749 window.setPagePosition(x, y);
750 windowSlot++;
751 if (x + windowSize.width > rect.x + rect.width || y + windowSize.height > rect.y + rect.height) {
752 x = rect.x;
753 y = rect.y;
754 windowSlot = 0;
755 }
756 }
757
758 public void closeWindow(SVGWindow window) {
759 GWT.log("closeWindow()");
760 if (window != null) {
761 window.hide();
762 }
763 }
764
765 public static String getParameter(String param) {
766 return com.google.gwt.user.client.Window.Location.getParameter(param);
767 }
768
769 public SVGWindow getActiveWindow() {
770 return activeWindow;
771 }
772
773 public SVGModel getActiveModel() {
774 if (activeWindow != null) {
775 return activeWindow.getSvgModel();
776 }
777 return null;
778 }
779
780 public SVGWindow getWindow(SVGElement element) {
781 SVGSVGElement svg = element.getOwnerSVGElement();
782 for (SVGWindow svgWindow : svgWindows) {
783 if (svg == svgWindow.getSvgModel().getSvgElement().getElement()) {
784 return svgWindow;
785 }
786 }
787 return null;
788 }
789
790 public void about() {
791 GWT.log("about()");
792 if (aboutDialog == null) {
793 aboutDialog = new AboutDialog();
794 }
795 aboutDialog.show();
796 }
797 public Rectangle getRectangle() {
798 int windowBarHeight = getWindowBarHeight();
799 Size commandBarSize = commandToolBar.getSize();
800 Size viewPortSize = viewport.getSize();
801 Rectangle rect = new Rectangle(0, windowBarHeight, viewPortSize.width, viewPortSize.height - windowBarHeight - commandBarSize.height);
802 return rect;
803 }
804 public static final int getWindowBarHeight() {
805 return 27;
806 }
807
808 private void update() {
809 boolean hasActiveWindow = svgWindows.size() > 0;
810 exportAsSvgMenuItem.setEnabled(hasActiveWindow);
811 closeWindowItem.setEnabled(hasActiveWindow);
812 tileWindowsItem.setEnabled(hasActiveWindow);
813 stackWindowsItem.setEnabled(hasActiveWindow);
814 resetViewItem.setEnabled(hasActiveWindow);
815 displayWindowMenuItem.setEnabled(svgWindows.size() > 0);
816 }
817
818 public static final native void log(String msg)
819
820 ;
821
822 public void inspector() {
823 GWT.log("inspector()");
824 if (inspectorWindow == null) {
825 inspectorWindow = new InspectorWindow();
826 }
827 inspectorWindow.show();
828 if (activeWindow != null) {
829 activeWindow.updateSelectionListeners();
830 }
831 }
832
833 public CssContextModel getCssContext() {
834 return cssContext;
835 }
836
837 public List<MetaModel<?>> getMetaModels() {
838 if (metaModels == null) {
839 metaModels = new ArrayList<MetaModel<?>>();
840 metaModels.add(SVGLineElementModel.getLineElementMetaModel());
841 metaModels.add(SVGCircleElementModel.getCircleElementMetaModel());
842 metaModels.add(SVGEllipseElementModel.getEllipseElementMetaModel());
843 metaModels.add(SVGRectElementModel.getRectElementMetaModel());
844 metaModels.add(SVGPolygonElementModel.getPolygonElementMetaModel());
845 metaModels.add(SVGPolylineElementModel.getPolylineElementMetaModel());
846 metaModels.add(SVGImageElementModel.getImageElementMetaModel());
847 }
848 return metaModels;
849 }
850
851
852
853
854
855 public CommandFactorySelector getCommandFactorySelector() {
856 if (commandFactorySelector == null) {
857 commandFactorySelector = new CommandFactorySelector();
858 }
859 return commandFactorySelector;
860 }
861
862
863
864
865 public EventBus getEventBus() {
866 if (eventBus == null) {
867 eventBus = new SimpleEventBus();
868 }
869 return eventBus;
870 }
871
872 public CommandFactoryToolBar getCommandToolBar() {
873 return commandToolBar;
874 }
875
876 public DecoratedImageCache getImageCache() {
877 return imageCache;
878 }
879
880 @Override
881 public void fireEvent(GwtEvent<?> event) {
882 eventBus.fireEventFromSource(event, this);
883 }
884
885 @Override
886 public HandlerRegistration addDeactivateWindowHandler(
887 DeactivateWindowHandler handler) {
888 return eventBus.addHandlerToSource(DeactivateWindowEvent.getType(), this, handler);
889 }
890
891 @Override
892 public HandlerRegistration addActivateWindowHandler(
893 ActivateWindowHandler handler) {
894 return eventBus.addHandlerToSource(ActivateWindowEvent.getType(), this, handler);
895 }
896
897 public static SvgrealApp getApp() {
898 if (instance == null) {
899 instance = new SvgrealApp();
900 }
901 return instance;
902 }
903 }